/**************************************************************************************** * ddc_txrx.c * Linux atm module implementation. * * 2003 (c) Texas Instruments Inc. * * 8/15/2006 MK CQ10842: Added retval to capture the return of pHalFunc->Send * function to help with the debug when SAR fails to send packet. * 10/29/2006 AV Updating the DDC_malloc_rxbuffer() API to pass in the size. * 01/16/2007 MK CQ11287: Freeing buffer if the channel is not ready in DDC_sar_receive(). * 02/14/2007 EP Clean up psp trace. ****************************************************************************************/ #include "ddc_ti_dsl.h" /************************************************************ NEED FN HEADER ************************************************************/ /* Moved these definitions here for all modules to use. */ __inline__ void DDC_atm_data_invalidate(void *pmem, int size) { unsigned int i,Size=(((unsigned int)pmem)&0xf)+size; if(!pmem) return; for (i=0;ipSarHalFunc; /* Mode contains channel info */ ch = (mode & 0xFF); if(ch == RESERVED_OAM_CHANNEL) //15 { DDC_sar_process_unmatched_oam(frag_list, frag_count, packet_size, mode); bRet = pHalFunc->RxReturn(hal_receive_info, 0); #ifdef TIATM_INST_SUPP psp_trace_par(ATM_DRV_RX_EXIT, bRet); #endif return 0; } /*** Should we remove this check when we support multiple fragments in the Fraglist. ***/ if(frag_count > 1 || frag_list->len == 0) { DDA_printf("Packet fragment count > 1, not handle.\n"); bRet = pHalFunc->RxReturn(hal_receive_info, 0); #ifdef TIATM_INST_SUPP psp_trace_par(ATM_DRV_RX_EXIT, bRet); #endif return 1; } /* Added check to see if the channel is closed */ if(!priv->lut[ch].ready) { if((cnt++ %100) == 0) DDA_printf("Channel %d is closed. cnt=%d\n", ch, cnt); pHalFunc->RxReturn(hal_receive_info, 0); return 1; } DDC_atm_data_invalidate(frag_list->data, (int)frag_list->len); bRet = DDA_atm_receive(priv->dev, ch, packet_size, frag_list->OsInfo, frag_list->data); if(bRet==0) { sarStat.rxPktCnt++; sarStat.rxBytes += packet_size; pHalFunc->RxReturn(hal_receive_info, 1); } else { pHalFunc->RxReturn(hal_receive_info, 0); } #ifdef TIATM_INST_SUPP psp_trace_par(ATM_DRV_RX_EXIT, bRet); #endif return bRet; } #endif /* AR7_SAR */ #ifdef UR8_SAR int DDC_sar_receive(void *os_dev, DDC_NetPktObj * pkt, void *chan, Ptr arg) { int ch = (int) chan; DDC_DslPriv *priv = (DDC_DslPriv *)os_dev; unsigned int len = pkt->pktLength; unsigned int count = pkt->numBufs; static int cnt = 0; int bRet; if(!(len | count)) { return -1; } if(!priv->lut[ch].ready) { if((cnt++ %100) == 0) DDA_printf("Channel %d is closed. cnt=%d\n", ch, cnt); DDA_free_buffer(pkt->pktToken, NULL); //pHalFunc->RxReturn(hal_receive_info, 0); return 1; } //DDC_atm_data_invalidate(pkt->bufList->dataPtr, len); if(ch == RESERVED_OAM_CHANNEL) //15 { DDC_sar_process_unmatched_oam(pkt->bufList->dataPtr, len); return 0; } DDC_atm_data_invalidate(pkt->bufList->dataPtr, len); bRet = DDA_atm_receive(priv->dev, ch, len, pkt->pktToken, pkt->bufList->dataPtr); if(bRet == 0) { sarStat.rxPktCnt++; sarStat.rxBytes += len; //pHalFunc->RxReturn(hal_receive_info, 1); } else { dgprintf (4, "%s: dropped packet for channel %d \n",__FUNCTION__, ch); sarStat.rxErrors++; //pHalFunc->RxReturn(hal_receive_info, 0); } return 0; } #endif /* UR8_SAR */ /************************************************************ NEED FN HEADER ************************************************************/ int DDC_sar_send_packet(DDC_DslPriv *priv, int chan, void *new_skb, void *data,unsigned int len, int priority) { #ifdef AR7_SAR FRAGLIST fragList; unsigned int mode; HAL_FUNCTIONS *pHalFunc; HAL_DEVICE *pHalDev; int retval; dgprintf(4, "DDC_sar_send_packet\n"); pHalFunc = (HAL_FUNCTIONS *)priv->pSarHalFunc; pHalDev = (HAL_DEVICE *)priv->pSarHalDev; fragList.len = len; fragList.data = (void *)data; xdump((char *)fragList.data , fragList.len, 6); /*mode bit 31-19 unused 18 oam cell, 1 = true, 0=false 17-16 oam type, 0=F4 seg, 1=F4 End, 2=F5 seg, 3=F5 end 15-08 transimit queue, current, 0=priority queue, 1=normal queue 07-00 channel number */ mode = 0; mode |= (0xff & chan); mode |= ((0xff & priority) << 8); dgprintf(4, "mode = %d\n", mode); DDC_atm_data_writeback(fragList.data, len); if(pHalFunc->Send(pHalDev, &fragList, 1, len, new_skb, mode) != 0) { dgprintf(1, "SAR hal failed to send packet.\n"); return 1; } #endif /* AR7_SAR */ #ifdef UR8_SAR DDC_NetPktObj pkt; DDC_NetBufObj buf; int retval = 0; unsigned int mode = 0; buf.dataPtr = data; buf.length = len; buf.bufToken = new_skb; pkt.bufList = &buf; pkt.numBufs = 1; pkt.pktLength = len; pkt.pktToken = new_skb; /** (Note: Bits 15-0 map directly to CPPI4 BD Word 2 bits 31-16.) * 17-16 Priority Queue. 0-3. (Only valid for Ch 0) * 15-12 Packet Type * 11 Descriptor Type (0 = Host, 1 = Embedded Mode) * 10-8 Additional Buffer Count (0-7). Set to 0 for Host Mode. * 7 Reserved * 6-4 Protocol Specific Region Offset. Set to 0 for Host Mode. * 3-0 Reserved. */ mode = (PKT_TYPE_AAL5 << 12) | (priority << 16); DDC_atm_data_writeback(buf.dataPtr, len); //DDA_printf("%s: len = %d \n", __FUNCTION__, len); retval = DDC_cpsarSend(priv->SarDev, &pkt, chan, (void *)mode); if(retval) { dgprintf(1, "SAR hal failed to send packet.\n"); return retval; } #endif /* UR8_SAR */ //DDC_sar_get_stats(priv); sarStat.txPktCnt++; sarStat.txBytes +=len; return 0; } #ifdef UR8_SAR __inline__ int DDC_send_complete(void* hDDA, void *netDataTokens, int numTokens, unsigned int channel) { return(DDA_send_complete(netDataTokens, numTokens)); } #endif #ifdef AR7_SAR __inline__ int DDC_send_complete(OS_SENDINFO *OsSendInfo) { return(DDA_send_complete(OsSendInfo, 1)); } #endif #ifdef UR8_SAR void *DDC_malloc_rxbuffer(void *hDDA, void *dataToken, unsigned int size, unsigned int channel) { DDC_DslPriv *priv = (DDC_DslPriv *)hDDA; //DDA_printf("%s: Allocating buffers for ch %d with size %d \n", __FUNCTION__, channel, priv->SarDev->rxCppi[channel].chInfo.RxBufSize); return(DDA_malloc_rxbuffer(size, 0, 0,priv->lut[channel].vcc, NULL, dataToken, priv->dev)); } #endif #ifdef UR8_SAR void DDC_free_rxbuffer(void *hDDA, void *dataToken, unsigned int channel) { DDA_free_buffer((void *)dataToken, NULL); } #endif