static VOID DumpIpv6Header(IPV6Header *pstIpv6Header) { UCHAR ucVersion; UCHAR ucPrio; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header---"); ucVersion = pstIpv6Header->ucVersionPrio & 0xf0; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Version : %x\n", ucVersion); ucPrio = pstIpv6Header->ucVersionPrio & 0x0f; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Priority : %x\n", ucPrio); /* * BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, * "Flow Label : %x\n",(pstIpv6Header->ucVersionPrio &0xf0); */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Payload Length : %x\n", ntohs(pstIpv6Header->usPayloadLength)); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Next Header : %x\n", pstIpv6Header->ucNextHeader); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Hop Limit : %x\n", pstIpv6Header->ucHopLimit); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Src Address :\n"); DumpIpv6Address(pstIpv6Header->ulSrcIpAddress); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Dest Address :\n"); DumpIpv6Address(pstIpv6Header->ulDestIpAddress); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header End---"); }
static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload,USHORT *pusSrcPort,USHORT *pusDestPort,USHORT usPayloadLength,UCHAR ucNextHeader) { UCHAR *pIpv6HdrScanContext = pucPayload; BOOLEAN bDone = FALSE; UCHAR ucHeaderType =0; UCHAR *pucNextHeader = NULL; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); if( !pucPayload || (usPayloadLength == 0)) { return 0; } *pusSrcPort = *pusDestPort = 0; ucHeaderType = ucNextHeader; while(!bDone) { pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext,&ucHeaderType,&bDone,&usPayloadLength); if(bDone) { if((ucHeaderType==TCP_HEADER_TYPE) || (ucHeaderType == UDP_HEADER_TYPE)) { *pusSrcPort=*((PUSHORT)(pucNextHeader)); *pusDestPort=*((PUSHORT)(pucNextHeader+2)); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nProtocol Ports - Src Port :0x%x Dest Port : 0x%x",ntohs(*pusSrcPort),ntohs(*pusDestPort)); } break; } } return ucHeaderType; }
static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, IN S_CLASSIFIER_ENTRY *pstClassifierEntry, S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule, B_UINT8 u8AssociatedPHSI) { S_PHS_RULE *pstAddPhsRule = NULL; UINT nPhsRuleIndex = 0; BOOLEAN bPHSRuleOrphaned = FALSE; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); psPhsRule->u8RefCnt =0; /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry*/ bPHSRuleOrphaned = DerefPhsRule( uiClsId, psaClassifiertable, pstClassifierEntry->pstPhsRule); //Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF nPhsRuleIndex =GetPhsRuleEntry(psaClassifiertable,u8AssociatedPHSI, eActiveClassifierRuleContext, &pstAddPhsRule); if(PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier"); if(psPhsRule->u8PHSI == 0) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n"); return ERR_PHS_INVALID_PHS_RULE; } //Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId if(FALSE == bPHSRuleOrphaned) { pstClassifierEntry->pstPhsRule = kmalloc(sizeof(S_PHS_RULE), GFP_KERNEL); if(NULL == pstClassifierEntry->pstPhsRule) { return ERR_PHSRULE_MEMALLOC_FAIL; } } memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE)); } else { //Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule"); if(bPHSRuleOrphaned) { kfree(pstClassifierEntry->pstPhsRule); pstClassifierEntry->pstPhsRule = NULL; } pstClassifierEntry->pstPhsRule = pstAddPhsRule; } pstClassifierEntry->bUsed = TRUE; pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI; pstClassifierEntry->uiClassifierRuleId = uiClsId; pstClassifierEntry->pstPhsRule->u8RefCnt++; pstClassifierEntry->bUnclassifiedPHSRule = pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule; return PHS_SUCCESS; }
static void usbbcm_disconnect (struct usb_interface *intf) { PS_INTERFACE_ADAPTER psIntfAdapter = NULL; PMINI_ADAPTER psAdapter = NULL; struct usb_device *udev = NULL; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Usb disconnected"); if(intf == NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "intf pointer is NULL"); return; } psIntfAdapter = usb_get_intfdata(intf); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "psIntfAdapter 0x%x",(unsigned int)psIntfAdapter); if(psIntfAdapter == NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InterfaceAdapter pointer is NULL"); return; } psAdapter = psIntfAdapter->psAdapter; if(psAdapter->bDoSuspend) intf->needs_remote_wakeup = 0; psAdapter->device_removed = TRUE ; usb_set_intfdata(intf, NULL); InterfaceAdapterFree(psIntfAdapter); udev = interface_to_usbdev (intf); usb_put_dev(udev); usb_deregister_dev (intf, &usbbcm_class); }
static int bcm_compare_buff_contents(unsigned char *readbackbuff, unsigned char *buff,unsigned int len) { int retval = STATUS_SUCCESS; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); if((len-sizeof(unsigned int))<4) { if(memcmp(readbackbuff , buff, len)) { retval=-EINVAL; } } else { len-=4; while(len) { if(*(unsigned int*)&readbackbuff[len] != *(unsigned int *)&buff[len]) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper"); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Val from Binary %x, Val From Read Back %x ", *(unsigned int *)&buff[len], *(unsigned int*)&readbackbuff[len]); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len); retval=-EINVAL; break; } len-=4; } } return retval; }
int phs_decompress(unsigned char *in_buf,unsigned char *out_buf, S_PHS_RULE *decomp_phs_rules,UINT *header_size) { int phss,size=0; S_PHS_RULE *tmp_memb; int bit,i=0; unsigned char *phsf,*phsm; int in_buf_len = *header_size-1; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); in_buf++; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"====>\n"); *header_size = 0; if((decomp_phs_rules == NULL )) return 0; tmp_memb = decomp_phs_rules; //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi)); //*header_size = tmp_memb->u8PHSFLength; phss = tmp_memb->u8PHSS; phsf = tmp_memb->u8PHSF; phsm = tmp_memb->u8PHSM; if(phss > MAX_PHS_LENGTHS) phss = MAX_PHS_LENGTHS; //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI %d phss %d index %d",phsi,phss,index)); while((phss > 0) && (size < in_buf_len)) { bit = ((*phsm << i)& SUPPRESS); if(bit == SUPPRESS) { *out_buf = *phsf; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d", phss,*phsf,*out_buf); } else { *out_buf = *in_buf; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d", phss,*in_buf,*out_buf); in_buf++; size++; } out_buf++; phsf++; phss--; i++; *header_size=*header_size + 1; if(i > MAX_NO_BIT) { i=0; phsm++; } } return size; }
void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension) { int i,j,k,l; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n Dumping PHS Rules : \n"); for(i=0;i<MAX_SERVICEFLOWS;i++) { S_SERVICEFLOW_ENTRY stServFlowEntry = pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i]; if(stServFlowEntry.bUsed) { for(j=0;j<MAX_PHSRULE_PER_SF;j++) { for(l=0;l<2;l++) { S_CLASSIFIER_ENTRY stClsEntry; if(l==0) { stClsEntry = stServFlowEntry.pstClassifierTable->stActivePhsRulesList[j]; if(stClsEntry.bUsed) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Active PHS Rule : \n"); } else { stClsEntry = stServFlowEntry.pstClassifierTable->stOldPhsRulesList[j]; if(stClsEntry.bUsed) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Old PHS Rule : \n"); } if(stClsEntry.bUsed) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X",stServFlowEntry.uiVcid); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X",stClsEntry.uiClassifierRuleId); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X",stClsEntry.u8PHSI); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n"); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X",stClsEntry.pstPhsRule->u8PHSI); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ",stClsEntry.pstPhsRule->u8PHSFLength); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : "); for(k=0;k<stClsEntry.pstPhsRule->u8PHSFLength;k++) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSF[k]); } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X",stClsEntry.pstPhsRule->u8PHSMLength); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :"); for(k=0;k<stClsEntry.pstPhsRule->u8PHSMLength;k++) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSM[k]); } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ",stClsEntry.pstPhsRule->u8PHSS); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X",stClsEntry.pstPhsRule->u8PHSV); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n"); } } } } } }
static BOOLEAN MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule, IPV6Header *pstIpv6Header) { UINT uiLoopIndex = 0; UINT uiIpv6AddIndex = 0; UINT uiIpv6AddrNoLongWords = 4; ULONG aulDestIP[4]; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); /* * This is the no. of Destination Addresses * ie Range of IP Addresses contained in the classifier rule * for which we need to match */ UINT uiCountIPDestinationAddresses = (UINT)pstClassifierRule->ucIPDestinationAddressLength; if (uiCountIPDestinationAddresses == 0) return TRUE; /* First Convert the Ip Address in the packet to Host Endian order */ for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) aulDestIP[uiIpv6AddIndex] = ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]); for (uiLoopIndex = 0; uiLoopIndex < uiCountIPDestinationAddresses; uiLoopIndex += uiIpv6AddrNoLongWords) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Received Packet :\n "); DumpIpv6Address(aulDestIP); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Mask In Classifier Rule :\n"); DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex]); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Classifier Rule :\n"); DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex]); for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { if ((pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulDestIP[uiIpv6AddIndex]) != pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { /* * Match failed for current Ipv6 Address. * Try next Ipv6 Address */ break; } if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { /* Match Found */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Destination Ip Address Matched\n"); return TRUE; } } } return FALSE; }
VOID DumpIpv6Address(ULONG *puIpv6Address) { UINT uiIpv6AddrNoLongWords = 4; UINT uiIpv6AddIndex=0; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++) { BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, ":%lx",puIpv6Address[uiIpv6AddIndex]); } }
static INT bcm_close(struct net_device *dev) { struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev); if (netif_msg_ifdown(Adapter)) pr_info(PFX "%s: disabling interface\n", dev->name); netif_carrier_off(dev); netif_stop_queue(dev); return 0; }
static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer, unsigned char *phsf,unsigned char *phsm,unsigned int phss, unsigned int phsv,UINT* new_header_size) { unsigned int size=0; int bit,i=0; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf PHSM - 0x%X",*phsm); if(phss>(*new_header_size)) { phss=*new_header_size; } while(phss > 0) { bit = ((*phsm << i)& SUPPRESS); if(bit == SUPPRESS) { if(*in_buffer != *phsf) { if(phsv == VERIFY) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf failed for field %d buf %d phsf %d",phss,*in_buffer,*phsf); return STATUS_PHS_NOCOMPRESSION; } } else BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success for field %d buf %d phsf %d",phss,*in_buffer,*phsf); } else { *out_buffer = *in_buffer; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In copying_header input %d out %d",*in_buffer,*out_buffer); out_buffer++; size++; } in_buffer++; phsf++; phss--; i++; if(i > MAX_NO_BIT) { i=0; phsm++; } } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success"); *new_header_size = size; return STATUS_PHS_COMPRESSED; }
static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header) { UINT uiLoopIndex=0; UINT uiIpv6AddIndex=0; UINT uiIpv6AddrNoLongWords = 4; ULONG aulSrcIP[4]; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); /* //This is the no. of Src Addresses ie Range of IP Addresses contained //in the classifier rule for which we need to match */ UINT uiCountIPSrcAddresses = (UINT)pstClassifierRule->ucIPSourceAddressLength; if(0 == uiCountIPSrcAddresses) return TRUE; //First Convert the Ip Address in the packet to Host Endian order for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++) { aulSrcIP[uiIpv6AddIndex]=ntohl(pstIpv6Header->ulSrcIpAddress[uiIpv6AddIndex]); } for(uiLoopIndex=0;uiLoopIndex<uiCountIPSrcAddresses;uiLoopIndex+=uiIpv6AddrNoLongWords) { BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Received Packet : \n "); DumpIpv6Address(aulSrcIP); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Mask In Classifier Rule: \n"); DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex]); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Classifier Rule : \n"); DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex]); for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++) { if((pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulSrcIP[uiIpv6AddIndex]) != pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { //Match failed for current Ipv6 Address.Try next Ipv6 Address break; } if(uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { //Match Found BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Src Ip Address Matched\n"); return TRUE; } } } return FALSE; }
static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable) { int i,j; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n"); if(psServiceFlowRulesTable) { for(i=0;i<MAX_SERVICEFLOWS;i++) { S_SERVICEFLOW_ENTRY stServiceFlowEntry = psServiceFlowRulesTable->stSFList[i]; S_CLASSIFIER_TABLE *pstClassifierRulesTable = stServiceFlowEntry.pstClassifierTable; if(pstClassifierRulesTable) { for(j=0;j<MAX_PHSRULE_PER_SF;j++) { if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule) { if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule ->u8RefCnt) pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule ->u8RefCnt--; if(0==pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule ->u8RefCnt) kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule); pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL; } if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule) { if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule ->u8RefCnt) pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule ->u8RefCnt--; if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule ->u8RefCnt) kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule); pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL; } } kfree(pstClassifierRulesTable); stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL; } } } kfree(psServiceFlowRulesTable); psServiceFlowRulesTable = NULL; }
/*++ PhsUpdateClassifierRule Routine Description: Exported function to add or modify a PHS Rule. Arguments: IN void* pvContext - PHS Driver Specific Context IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. IN S_PHS_RULE *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table. Return Value: 0 if successful, >0 Error. --*/ ULONG PhsUpdateClassifierRule(IN void* pvContext, IN B_UINT16 uiVcid , IN B_UINT16 uiClsId , IN S_PHS_RULE *psPhsRule, IN B_UINT8 u8AssociatedPHSI) { ULONG lStatus =0; UINT nSFIndex =0 ; S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS With Corr2 Changes \n"); if(pDeviceExtension == NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Invalid Device Extension\n"); return ERR_PHS_INVALID_DEVICE_EXETENSION; } if(u8AssociatedPHSI == 0) { return ERR_PHS_INVALID_PHS_RULE; } /* Retrieve the SFID Entry Index for requested Service Flow */ nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid,&pstServiceFlowEntry); if(nSFIndex == PHS_INVALID_TABLE_INDEX) { /* This is a new SF. Create a mapping entry for this */ lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId, pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI); return lStatus; } /* SF already Exists Add PHS Rule to existing SF */ lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId, pstServiceFlowEntry, psPhsRule, u8AssociatedPHSI); return lStatus; }
ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI) { ULONG lStatus =0; UINT nSFIndex =0, nClsidIndex =0 ; S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n"); if(pDeviceExtension) { //Retrieve the SFID Entry Index for requested Service Flow nSFIndex = GetServiceFlowEntry(pDeviceExtension ->pstServiceFlowPhsRulesTable,uiVcid,&pstServiceFlowEntry); if(nSFIndex == PHS_INVALID_TABLE_INDEX) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n"); return ERR_SF_MATCH_FAIL; } pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable; if(pstClassifierRulesTable) { for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++) { if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) { if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) { if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--; if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule); memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY)); } } } } } return lStatus; }
static void bcm_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev); struct bcm_interface_adapter *psIntfAdapter = Adapter->pvInterfaceAdapter; struct usb_device *udev = interface_to_usbdev(psIntfAdapter->interface); strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); strlcpy(info->version, DRV_VERSION, sizeof(info->version)); snprintf(info->fw_version, sizeof(info->fw_version), "%u.%u", Adapter->uiFlashLayoutMajorVersion, Adapter->uiFlashLayoutMinorVersion); usb_make_path(udev, info->bus_info, sizeof(info->bus_info)); }
/*++ PhsDeleteClassifierRule Routine Description: Exported function to Delete a PHS Rule for the SFID,CLSID Pair. Arguments: IN void* pvContext - PHS Driver Specific Context IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. Return Value: 0 if successful, >0 Error. --*/ ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16 uiClsId) { ULONG lStatus =0; UINT nSFIndex =0, nClsidIndex =0 ; S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; if(pDeviceExtension) { //Retrieve the SFID Entry Index for requested Service Flow nSFIndex = GetServiceFlowEntry(pDeviceExtension ->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); if(nSFIndex == PHS_INVALID_TABLE_INDEX) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"SFID Match Failed\n"); return ERR_SF_MATCH_FAIL; } nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry); if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) { if(pstClassifierEntry->pstPhsRule) { if(pstClassifierEntry->pstPhsRule->u8RefCnt) pstClassifierEntry->pstPhsRule->u8RefCnt--; if(0==pstClassifierEntry->pstPhsRule->u8RefCnt) kfree(pstClassifierEntry->pstPhsRule); } memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY)); } nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, uiClsId,eOldClassifierRuleContext,&pstClassifierEntry); if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) { kfree(pstClassifierEntry->pstPhsRule); memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY)); } } return lStatus; }
static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev) { struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev); u16 qindex = skb_get_queue_mapping(skb); if (Adapter->device_removed || !Adapter->LinkUpStatus) goto drop; if (Adapter->TransferMode != IP_PACKET_ONLY_MODE) goto drop; if (INVALID_QUEUE_INDEX == qindex) goto drop; if (Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP) return NETDEV_TX_BUSY; /* Now Enqueue the packet */ if (netif_msg_tx_queued(Adapter)) pr_info(PFX "%s: enqueueing packet to queue %d\n", dev->name, 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); /* FIXME - this is racy and incorrect, replace with work queue */ if (!atomic_read(&Adapter->TxPktAvail)) { atomic_set(&Adapter->TxPktAvail, 1); wake_up(&Adapter->tx_packet_wait_queue); } return NETDEV_TX_OK; drop: dev_kfree_skb(skb); return NETDEV_TX_OK; }
INT flushAllAppQ(void) { PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); PPER_TARANG_DATA pTarang = NULL; struct sk_buff *PacketToDrop = NULL; for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) { while (pTarang->RxAppControlHead != NULL) { PacketToDrop = pTarang->RxAppControlHead; DEQUEUEPACKET(pTarang->RxAppControlHead, pTarang->RxAppControlTail); dev_kfree_skb(PacketToDrop); } pTarang->AppCtrlQueueLen = 0; memset((PVOID)&pTarang->stDroppedAppCntrlMsgs, 0, sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES)); } return STATUS_SUCCESS; }
INT flushAllAppQ(void) { struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); struct bcm_tarang_data *pTarang = NULL; struct sk_buff *PacketToDrop = NULL; for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) { while (pTarang->RxAppControlHead != NULL) { PacketToDrop = pTarang->RxAppControlHead; DEQUEUEPACKET(pTarang->RxAppControlHead, pTarang->RxAppControlTail); dev_kfree_skb(PacketToDrop); } pTarang->AppCtrlQueueLen = 0; /* dropped contrl packet statistics also should be reset. */ memset((PVOID)&pTarang->stDroppedAppCntrlMsgs, 0, sizeof(struct bcm_mibs_dropped_cntrl_msg)); } return STATUS_SUCCESS; }
//----------------------------------------------------------------------------- // Procedure: phs_compress // // Description: This routine suppresses the static fields within the packet.Before // that it will verify the fields to be suppressed with the corresponding fields in the // phsf. For verification it checks the phsv field of PHS rule. If set and verification // succeeds it suppresses the field.If any one static field is found different none of // the static fields are suppressed then the packet is sent as uncompressed packet with // phsi=0. // // Arguments: // phs_rule - ptr to PHS rule. // in_buf - ptr to incoming packet buffer. // out_buf - ptr to output buffer where the suppressed header is copied. // header_size - ptr to field which holds the phss. // // Returns: // size-The number of bytes copied into the output buffer i.e dynamic fields // 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails. //----------------------------------------------------------------------------- static int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf ,unsigned char *out_buf,UINT *header_size,UINT *new_header_size) { unsigned char *old_addr = out_buf; int suppress = 0; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if(phs_rule == NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nphs_compress(): phs_rule null!"); *out_buf = ZERO_PHSI; return STATUS_PHS_NOCOMPRESSION; } if(phs_rule->u8PHSS <= *new_header_size) { *header_size = phs_rule->u8PHSS; } else { *header_size = *new_header_size; } //To copy PHSI out_buf++; suppress = verify_suppress_phsf(in_buf,out_buf,phs_rule->u8PHSF, phs_rule->u8PHSM, phs_rule->u8PHSS, phs_rule->u8PHSV,new_header_size); if(suppress == STATUS_PHS_COMPRESSED) { *old_addr = (unsigned char)phs_rule->u8PHSI; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress phsi %d",phs_rule->u8PHSI); } else { *old_addr = ZERO_PHSI; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress PHSV Verification failed"); } return suppress; }
static INT bcm_open(struct net_device *dev) { struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev); if (Adapter->fw_download_done == false) { pr_notice(PFX "%s: link up failed (download in progress)\n", dev->name); return -EBUSY; } if (netif_msg_ifup(Adapter)) pr_info(PFX "%s: enabling interface\n", dev->name); if (Adapter->LinkUpStatus) { if (netif_msg_link(Adapter)) pr_info(PFX "%s: link up\n", dev->name); netif_carrier_on(Adapter->dev); netif_start_queue(Adapter->dev); } return 0; }
/*this is transmit call-back(BULK OUT)*/ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) { struct bcm_usb_tcb *pTcb = (struct bcm_usb_tcb *)urb->context; struct bcm_interface_adapter *psIntfAdapter = pTcb->psIntfAdapter; struct bcm_link_request *pControlMsg = (struct bcm_link_request *)urb->transfer_buffer; struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter; bool bpowerDownMsg = false; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if (unlikely(netif_msg_tx_done(Adapter))) pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name, urb->status); if (urb->status != STATUS_SUCCESS) { if (urb->status == -EPIPE) { psIntfAdapter->psAdapter->bEndPointHalted = TRUE; wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); } else { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Tx URB has got cancelled. status :%d", urb->status); } } pTcb->bUsed = false; atomic_dec(&psIntfAdapter->uNumTcbUsed); if (TRUE == psAdapter->bPreparingForLowPowerMode) { prepare_low_power_mode(urb, psIntfAdapter, psAdapter, Adapter, pControlMsg, &bpowerDownMsg); } usb_free_coherent(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma); }
/*this is transmit call-back(BULK OUT)*/ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) { struct bcm_usb_tcb *pTcb = (struct bcm_usb_tcb *)urb->context; struct bcm_interface_adapter *psIntfAdapter = pTcb->psIntfAdapter; struct bcm_link_request *pControlMsg = (struct bcm_link_request *)urb->transfer_buffer; struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter; bool bpowerDownMsg = false; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if (unlikely(netif_msg_tx_done(Adapter))) pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name, urb->status); if (urb->status != STATUS_SUCCESS) { if (urb->status == -EPIPE) { psIntfAdapter->psAdapter->bEndPointHalted = TRUE; wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); } else { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Tx URB has got cancelled. status :%d", urb->status); } } pTcb->bUsed = false; atomic_dec(&psIntfAdapter->uNumTcbUsed); if (TRUE == psAdapter->bPreparingForLowPowerMode) { if (((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) && (pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) { bpowerDownMsg = TRUE; /* This covers the bus err while Idle Request msg sent down. */ if (urb->status != STATUS_SUCCESS) { psAdapter->bPreparingForLowPowerMode = false; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Idle Mode Request msg failed to reach to Modem"); /* Signalling the cntrl pkt path in Ioctl */ wake_up(&psAdapter->lowpower_mode_wait_queue); StartInterruptUrb(psIntfAdapter); goto err_exit; } if (psAdapter->bDoSuspend == false) { psAdapter->IdleMode = TRUE; /* since going in Idle mode completed hence making this var false */ psAdapter->bPreparingForLowPowerMode = false; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in Idle Mode State..."); /* Signalling the cntrl pkt path in Ioctl*/ wake_up(&psAdapter->lowpower_mode_wait_queue); } } else if ((pControlMsg->Leader.Status == LINK_UP_CONTROL_REQ) && (pControlMsg->szData[0] == LINK_UP_ACK) && (pControlMsg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) && (pControlMsg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) { /* This covers the bus err while shutdown Request msg sent down. */ if (urb->status != STATUS_SUCCESS) { psAdapter->bPreparingForLowPowerMode = false; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Shutdown Request Msg failed to reach to Modem"); /* Signalling the cntrl pkt path in Ioctl */ wake_up(&psAdapter->lowpower_mode_wait_queue); StartInterruptUrb(psIntfAdapter); goto err_exit; } bpowerDownMsg = TRUE; if (psAdapter->bDoSuspend == false) { psAdapter->bShutStatus = TRUE; /* since going in shutdown mode completed hence making this var false */ psAdapter->bPreparingForLowPowerMode = false; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in shutdown Mode State..."); /* Signalling the cntrl pkt path in Ioctl */ wake_up(&psAdapter->lowpower_mode_wait_queue); } } if (psAdapter->bDoSuspend && bpowerDownMsg) { /* issuing bus suspend request */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Issuing the Bus suspend request to USB stack"); psIntfAdapter->bPreparingForBusSuspend = TRUE; schedule_work(&psIntfAdapter->usbSuspendWork); } } err_exit: usb_free_coherent(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma); }
VOID reply_to_arp_request(struct sk_buff *skb) { PMINI_ADAPTER Adapter; struct ArpHeader *pArpHdr = NULL; struct ethhdr *pethhdr = NULL; UCHAR uiIPHdr[4]; /* Check for valid skb */ if(skb == NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid skb: Cannot reply to ARP request\n"); return; } Adapter = GET_BCM_ADAPTER(skb->dev); /* Print the ARP Request Packet */ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP Packet Dump :"); BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len); /* * Extract the Ethernet Header and Arp Payload including Header */ pethhdr = (struct ethhdr *)skb->data; pArpHdr = (struct ArpHeader *)(skb->data+ETH_HLEN); if(Adapter->bETHCSEnabled) { if(memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN)) { bcm_kfree_skb(skb); return; } } // Set the Ethernet Header First. memcpy(pethhdr->h_dest, pethhdr->h_source, ETH_ALEN); if(!memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN)) { pethhdr->h_source[5]++; } /* Set the reply to ARP Reply */ pArpHdr->arp.ar_op = ntohs(ARPOP_REPLY); /* Set the HW Address properly */ memcpy(pArpHdr->ar_sha, pethhdr->h_source, ETH_ALEN); memcpy(pArpHdr->ar_tha, pethhdr->h_dest, ETH_ALEN); // Swapping the IP Adddress memcpy(uiIPHdr,pArpHdr->ar_sip,4); memcpy(pArpHdr->ar_sip,pArpHdr->ar_tip,4); memcpy(pArpHdr->ar_tip,uiIPHdr,4); /* Print the ARP Reply Packet */ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP REPLY PACKET: "); /* Send the Packet to upper layer */ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len); skb->protocol = eth_type_trans(skb,skb->dev); skb->pkt_type = PACKET_HOST; // skb->mac.raw=skb->data+LEADER_SIZE; skb_set_mac_header (skb, LEADER_SIZE); netif_rx(skb); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "<=============\n"); return; }
/*this is transmit call-back(BULK OUT)*/ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) { PUSB_TCB pTcb= (PUSB_TCB)urb->context; PS_INTERFACE_ADAPTER psIntfAdapter = pTcb->psIntfAdapter; CONTROL_MESSAGE *pControlMsg = (CONTROL_MESSAGE *)urb->transfer_buffer; PMINI_ADAPTER psAdapter = psIntfAdapter->psAdapter ; BOOLEAN bpowerDownMsg = FALSE ; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); #if 0 struct timeval tv; UINT time_ms = 0; #endif if(urb->status != STATUS_SUCCESS) { if(urb->status == -EPIPE) { psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); } else { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Tx URB has got cancelled. status :%d", urb->status); } } pTcb->bUsed = FALSE; atomic_dec(&psIntfAdapter->uNumTcbUsed); if(TRUE == psAdapter->bPreparingForLowPowerMode) { #if 0 do_gettimeofday(&tv); time_ms = tv.tv_sec *1000 + tv.tv_usec/1000; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " %s Idle Mode ACK_Sent got from device at time :0x%x", __FUNCTION__, time_ms); #endif if(((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) && (pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) { bpowerDownMsg = TRUE ; //This covers the bus err while Idle Request msg sent down. if(urb->status != STATUS_SUCCESS) { psAdapter->bPreparingForLowPowerMode = FALSE ; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Idle Mode Request msg failed to reach to Modem"); //Signalling the cntrl pkt path in Ioctl wake_up(&psAdapter->lowpower_mode_wait_queue); StartInterruptUrb(psIntfAdapter); goto err_exit; } if(psAdapter->bDoSuspend == FALSE) { psAdapter->IdleMode = TRUE; //since going in Idle mode completed hence making this var false; psAdapter->bPreparingForLowPowerMode = FALSE ; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in Idle Mode State..."); //Signalling the cntrl pkt path in Ioctl wake_up(&psAdapter->lowpower_mode_wait_queue); } } else if((pControlMsg->Leader.Status == LINK_UP_CONTROL_REQ) && (pControlMsg->szData[0] == LINK_UP_ACK) && (pControlMsg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) && (pControlMsg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) { //This covers the bus err while shutdown Request msg sent down. if(urb->status != STATUS_SUCCESS) { psAdapter->bPreparingForLowPowerMode = FALSE ; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Shutdown Request Msg failed to reach to Modem"); //Signalling the cntrl pkt path in Ioctl wake_up(&psAdapter->lowpower_mode_wait_queue); StartInterruptUrb(psIntfAdapter); goto err_exit; } bpowerDownMsg = TRUE ; if(psAdapter->bDoSuspend == FALSE) { psAdapter->bShutStatus = TRUE; //since going in shutdown mode completed hence making this var false; psAdapter->bPreparingForLowPowerMode = FALSE ; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Host Entered in shutdown Mode State..."); //Signalling the cntrl pkt path in Ioctl wake_up(&psAdapter->lowpower_mode_wait_queue); } } if(psAdapter->bDoSuspend && bpowerDownMsg) { //issuing bus suspend request BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Issuing the Bus suspend request to USB stack"); psIntfAdapter->bPreparingForBusSuspend = TRUE; schedule_work(&psIntfAdapter->usbSuspendWork); } } err_exit : #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) usb_buffer_free(urb->dev, urb->transfer_buffer_length, #else usb_free_coherent(urb->dev, urb->transfer_buffer_length, #endif urb->transfer_buffer, urb->transfer_dma); }
static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader,BOOLEAN *bParseDone,USHORT *pusPayloadLength) { UCHAR *pucRetHeaderPtr = NULL; UCHAR *pucPayloadPtr = NULL; USHORT usNextHeaderOffset = 0 ; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); if((NULL == ppucPayload) || (*pusPayloadLength == 0) || (*bParseDone)) { *bParseDone = TRUE; return NULL; } pucRetHeaderPtr = *ppucPayload; pucPayloadPtr = *ppucPayload; if(!pucRetHeaderPtr || !pucPayloadPtr) { *bParseDone = TRUE; return NULL; } //Get the Nextt Header Type *bParseDone = FALSE; switch(*pucNextHeader) { case IPV6HDR_TYPE_HOPBYHOP: { BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 HopByHop Header"); usNextHeaderOffset+=sizeof(IPV6HopByHopOptionsHeader); } break; case IPV6HDR_TYPE_ROUTING: { IPV6RoutingHeader *pstIpv6RoutingHeader; BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Routing Header"); pstIpv6RoutingHeader = (IPV6RoutingHeader *)pucPayloadPtr; usNextHeaderOffset += sizeof(IPV6RoutingHeader); usNextHeaderOffset += pstIpv6RoutingHeader->ucNumAddresses * IPV6_ADDRESS_SIZEINBYTES; } break; case IPV6HDR_TYPE_FRAGMENTATION: { BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Fragmentation Header"); usNextHeaderOffset+= sizeof(IPV6FragmentHeader); } break; case IPV6HDR_TYPE_DESTOPTS: { IPV6DestOptionsHeader *pstIpv6DestOptsHdr = (IPV6DestOptionsHeader *)pucPayloadPtr; int nTotalOptions = pstIpv6DestOptsHdr->ucHdrExtLen; BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 DestOpts Header Header"); usNextHeaderOffset+= sizeof(IPV6DestOptionsHeader); usNextHeaderOffset+= nTotalOptions * IPV6_DESTOPTS_HDR_OPTIONSIZE ; } break; case IPV6HDR_TYPE_AUTHENTICATION: { IPV6AuthenticationHeader *pstIpv6AuthHdr = (IPV6AuthenticationHeader *)pucPayloadPtr; int nHdrLen = pstIpv6AuthHdr->ucLength; BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Authentication Header"); usNextHeaderOffset+= nHdrLen * 4; } break; case IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD: { BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Encrypted Security Payload Header"); *bParseDone = TRUE; } break; case IPV6_ICMP_HDR_TYPE: { BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " ICMP Header"); *bParseDone = TRUE; } break; case TCP_HEADER_TYPE: { BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nTCP Header"); *bParseDone = TRUE; } break; case UDP_HEADER_TYPE: { BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nUDP Header"); *bParseDone = TRUE; } break; default : { *bParseDone = TRUE; } break; } if(*bParseDone == FALSE) { if(*pusPayloadLength <= usNextHeaderOffset) { *bParseDone = TRUE; } else { *pucNextHeader = *pucPayloadPtr; pucPayloadPtr+=usNextHeaderOffset; (*pusPayloadLength)-=usNextHeaderOffset; } } *ppucPayload = pucPayloadPtr; return pucRetHeaderPtr; }
/*++ PhsDeCompress Routine Description: Exported function to restore the packet header in Rx path. Arguments: IN void* pvContext - PHS Driver Specific Context. IN B_UINT16 uiVcid - The Service Flow ID to which current packet header restoration applies. IN void *pvInputBuffer - The Input buffer containg suppressed packet header data OUT void *pvOutputBuffer - The output buffer returned by this function after restoration OUT UINT *pHeaderSize - The packet header size after restoration is returned in this parameter. Return Value: 0 if successful, >0 Error. --*/ ULONG PhsDeCompress(IN void* pvContext, IN B_UINT16 uiVcid, IN void *pvInputBuffer, OUT void *pvOutputBuffer, OUT UINT *pInHeaderSize, OUT UINT *pOutHeaderSize ) { UINT nSFIndex =0, nPhsRuleIndex =0 ; S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; S_PHS_RULE *pstPhsRule = NULL; UINT phsi; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; *pInHeaderSize = 0; if(pDeviceExtension == NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"Invalid Device Extension\n"); return ERR_PHS_INVALID_DEVICE_EXETENSION; } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"Restoring header\n"); phsi = *((unsigned char *)(pvInputBuffer)); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x\n",phsi); if(phsi == UNCOMPRESSED_PACKET ) { return STATUS_PHS_NOCOMPRESSION; } //Retrieve the SFID Entry Index for requested Service Flow nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid,&pstServiceFlowEntry); if(nSFIndex == PHS_INVALID_TABLE_INDEX) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n"); return ERR_SF_MATCH_FAIL; } nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,phsi, eActiveClassifierRuleContext,&pstPhsRule); if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) { //Phs Rule does not exist in active rules table. Lets try in the old rules table. nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, phsi,eOldClassifierRuleContext,&pstPhsRule); if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) { return ERR_PHSRULE_MATCH_FAIL; } } *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer, (PUCHAR)pvOutputBuffer,pstPhsRule,pOutHeaderSize); pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1; pstPhsRule->PHSModifiedNumPackets++; return STATUS_PHS_COMPRESSED; }
/*++ PhsCompress Routine Description: Exported function to compress the data using PHS. Arguments: IN void* pvContext - PHS Driver Specific Context. IN B_UINT16 uiVcid - The Service Flow ID to which current packet header compression applies. IN UINT uiClsId - The Classifier ID to which current packet header compression applies. IN void *pvInputBuffer - The Input buffer containg packet header data IN void *pvOutputBuffer - The output buffer returned by this function after PHS IN UINT *pOldHeaderSize - The actual size of the header before PHS IN UINT *pNewHeaderSize - The new size of the header after applying PHS Return Value: 0 if successful, >0 Error. --*/ ULONG PhsCompress(IN void* pvContext, IN B_UINT16 uiVcid, IN B_UINT16 uiClsId, IN void *pvInputBuffer, OUT void *pvOutputBuffer, OUT UINT *pOldHeaderSize, OUT UINT *pNewHeaderSize ) { UINT nSFIndex =0, nClsidIndex =0 ; S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL; S_PHS_RULE *pstPhsRule = NULL; ULONG lStatus =0; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; if(pDeviceExtension == NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Invalid Device Extension\n"); lStatus = STATUS_PHS_NOCOMPRESSION ; return lStatus; } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Suppressing header \n"); //Retrieve the SFID Entry Index for requested Service Flow nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid,&pstServiceFlowEntry); if(nSFIndex == PHS_INVALID_TABLE_INDEX) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"SFID Match Failed\n"); lStatus = STATUS_PHS_NOCOMPRESSION ; return lStatus; } nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, uiClsId,eActiveClassifierRuleContext,&pstClassifierEntry); if(nClsidIndex == PHS_INVALID_TABLE_INDEX) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"No PHS Rule Defined For Classifier\n"); lStatus = STATUS_PHS_NOCOMPRESSION ; return lStatus; } //get rule from SF id,Cls ID pair and proceed pstPhsRule = pstClassifierEntry->pstPhsRule; if(!ValidatePHSRuleComplete(pstPhsRule)) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS Rule Defined For Classifier But Not Complete\n"); lStatus = STATUS_PHS_NOCOMPRESSION ; return lStatus; } //Compress Packet lStatus = phs_compress(pstPhsRule,(PUCHAR)pvInputBuffer, (PUCHAR)pvOutputBuffer, pOldHeaderSize,pNewHeaderSize); if(lStatus == STATUS_PHS_COMPRESSED) { pstPhsRule->PHSModifiedBytes += *pOldHeaderSize - *pNewHeaderSize - 1; pstPhsRule->PHSModifiedNumPackets++; } else pstPhsRule->PHSErrorNumPackets++; return lStatus; }
void DumpFullPacket(UCHAR *pBuf,UINT nPktLen) { struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"Dumping Data Packet"); BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,pBuf,nPktLen); }