📄 ans.c
字号:
/* get the vlan id */ tag = bd_ans_GetVlanId(bps, iANSdata, rxd, peth_vlan_header); switch (iANSdata->tag_mode) { case IANS_BD_TAGGING_NONE: /* the rules are as follows for this situation: * vlan tagged - drop * priority tagged - strip, and send w/o OOB * untagged - receive and send w/o OOB * * As we are required to send attributed packets, * we will fill out just the last attribute and send it * if we accept the packet. */ DEBUGLOG("bd_ans_Receive: Tagging mode NONE\n"); if (Frame_is_tagged) { if (tag) { DEBUGLOG("bd_ans_Receive: Invalid VLAN packet\n"); return BD_ANS_FAILURE; } /* priority tagged */ if (iANSdata->vlan_offload_support == BD_ANS_FALSE) bd_ans_os_StripQtagSW(os_frame_data); } break; case IANS_BD_TAGGING_802_3AC: /* here we have the following rules: * VLAN-tagged: strip, report vlan id in tlv * Priority-tagged: drop * Untagged: receive with untagged tlv. * * The Untagged rule is there for 802.3ad requirements. * The 802.3ad spec allows for sending protocol packets * to and from the switch that ANS must be able to * receive. */ DEBUGLOG("bd_ans_Receive: Tagging mode 802.3ac\n"); if (Frame_is_tagged && !tag) { DEBUGLOG("bd_ans_Receive: Invalid VLAN packet\n"); return BD_ANS_FAILURE; } if (tlvlist_length == 0) { if (bd_ans_os_AllocateTLV(os_frame_data, os_tlv) == BD_ANS_FAILURE) { DEBUGLOG("bd_ans_Receive: Failed to allocated TLV\n"); return BD_ANS_FAILURE; } } if (Frame_is_tagged) { /* VLAN_ID TLV */ tlvlist_length += bd_ans_os_AttributeFill(IANS_ATTR_VLAN_ID, *os_tlv, tlvlist_length, (void *)&tag); if (iANSdata->vlan_offload_support == BD_ANS_FALSE) bd_ans_os_StripQtagSW(os_frame_data); } else { /* Send along, but untagged */ /* Untagged TLV */ tlvlist_length += bd_ans_os_AttributeFill(IANS_ATTR_TAGGING_UNTAGGED, *os_tlv, tlvlist_length, NULL); } break; default: DEBUGLOG("bd_ans_Receive: Invalid tagging mode\n"); return BD_ANS_FAILURE; }#endif /* allocate space for the last attribute TLV */ if (tlvlist_length == 0) { if (bd_ans_os_AllocateTLV(os_frame_data, os_tlv) == BD_ANS_FAILURE) { DEBUGLOG("bd_ans_Receive: failed to allocated TLV\n"); return BD_ANS_FAILURE; } } /* Last Attribute TLV */ tlvlist_length += bd_ans_os_AttributeFill(IANS_ATTR_LAST_ATTR, *os_tlv, tlvlist_length, NULL); *tlv_list_length = tlvlist_length; return BD_ANS_SUCCESS;} /* bd_ans_Transmit()**** This function is called when the driver has been configured to be** run in attributed mode (meaning we are receiving TLVs along with** the frame from ANS). It will perform the necessary operations ** according to what TLVs it finds. Note that it does NOT remove the** TLV list from the frame, it is up to the OS routines to do that ** if it is needed. **** Arguments: BOARD_PRIVATE_STRUCT *bps - a pointer to the adapters hw ** specific data structure.** HW_RX_DESCRIPTOR *rxd - pointer to hw dependent rx struct** FRAME_DATA *frame - pointer to an ethernet frame** OS_DATA *os_data - pointer to OS dependent frame data**** Returns: BD_ANS_STATUS - SUCCESS if command was processed ** successfully, FAILURE otherwise.*/ BD_ANS_STATUS bd_ans_Transmit(BOARD_PRIVATE_STRUCT *bps, iANSsupport_t *iANSdata, pPer_Frame_Attribute_Header pTLV, HW_TX_DESCRIPTOR *txd, OS_DATA **frame_ptr, UINT16 *vlanid){ DEBUGLOG("bd_ans_Transmit: enter\n"); #ifdef IANS_BASE_VLAN_TAGGING *vlanid = INVALID_VLAN_ID; /* if we are not in tagging mode, we have nothing to do */ if ( iANSdata->tag_mode == IANS_BD_TAGGING_NONE ) { return BD_ANS_SUCCESS; } /* traverse the list of TLVs until we get to the Last TLV. */ while (pTLV->AttributeID != IANS_ATTR_LAST_ATTR) { switch( pTLV->AttributeID ) { case IANS_ATTR_VLAN_ID: *vlanid = (UINT16) bd_ans_ExtractValue(pTLV); break; default: break; } /* switch AttributeID */ pTLV = GET_NEXT_TLV(pTLV); } DEBUGLOG1("bd_ans_Transmit: vlanid=%d\n", *vlanid); if (*vlanid != INVALID_VLAN_ID) { /* we can insert the qtag here. Doing this here instead of * within the while loop insures that the TLV list is no longer * needed, and we can recycle that extra memory (if needed) */ if (iANSdata->vlan_offload_support == BD_ANS_FALSE) { if (bd_ans_os_InsertQtagSW(bps, frame_ptr, vlanid) == BD_ANS_FAILURE) { DEBUGLOG("bd_ans_Transmit: Failed to insert qtag sw\n"); return BD_ANS_FAILURE; } } else { if (bd_ans_hw_InsertQtagHW(bps, txd, vlanid) == BD_ANS_FAILURE) { DEBUGLOG("bd_ans_Transmit: Failed to insert qtag hw\n"); return BD_ANS_FAILURE; } } }#endif return (BD_ANS_SUCCESS);}#ifdef IANS_BASE_VLAN_TAGGING/* bd_ans_IsQtagPacket()**** This function will determine whether or not a given packet has a** Qtag in it.**** Arguments: BOARD_PRIVATE_STRUCT *bps - pointer to the driver's private** data structure** iANSsupport_t *iANSdata - pointer to the required ANS** support structure.** HW_RX_DESCRIPTOR *rxd - pointer to hw specific rx frame** descriptor** eth_vlan_header_t *header - pointer to the head of the actual** frame data.**** Returns: BD_ANS_BOOLEAN BD_ANS_TRUE if it is a qtag packet** BD_ANS_FALSE if it is not.*/BD_ANS_BOOLEANbd_ans_IsQtagPacket(BOARD_PRIVATE_STRUCT *bps, iANSsupport_t *iANSdata, HW_RX_DESCRIPTOR *rxd, peth_vlan_header_t header){ /* if vlan_offload_support flag is set, then the driver has already * stripped the packet and will have a proprietary means of indicating * that it found a qtag packet. If so, call the hw module routine to * check it. */ DEBUGLOG("bd_ans_IsQtagPacket: enter\n"); if (iANSdata->vlan_offload_support) { return (bd_ans_hw_IsQtagPacket(bps, rxd)); } /* print the packet for debugging */ DEBUGLOG1("bd_ans_IsQtagPacket: type is 0x%x\n", ntohs(header->Qtag.EtherType)); return (ntohs(header->Qtag.EtherType) == QTAG_TYPE);} /* bd_ans_GetVlanId()**** This function will call the hw proprietary function to get the** vlan id if the driver supports vlan offloading, otherwise, it** will get the IEEE vlan id from the packet.**** TBD - what about ISL...**** Arguments: BOARD_PRIVATE_STRUCT *bps - pointer to the driver's private** data structure.** iANSsupport_t *iANSdata - pointer to the ans required** support structure.** HW_RX_DESCRIPTOR *rxd - pointer to the hw specific** rx frame descriptor** eth_vlan_header_t *header - pointer to the actual frame data**** Returns: UINT16 - the IEEE vlan id.*/UINT16bd_ans_GetVlanId(BOARD_PRIVATE_STRUCT *bps, iANSsupport_t *iANSdata, HW_RX_DESCRIPTOR *rxd, peth_vlan_header_t header) { if (iANSdata->vlan_offload_support) { return (bd_ans_hw_GetVlanId(bps, rxd)); } return (ntohs(header->Qtag.VLAN_ID) & VLAN_ID_MASK);} #endif/* bd_ans_AttributeFill()**** This routine will fill out a TLV based on a given attribute ID**** Arguments: iANS_Attribute_ID attr_id - id which identifies which ** TLV this is.** void *pTLV - pointer to where the TLV should** be copied.** void *data - optional data to be added to the** TLV (the V part)**** Returns: UINT32 - the length of the new TLV*/UINT32bd_ans_AttributeFill(iANS_Attribute_ID attr_id, void *pTLV, void *data){#ifdef IANS_BASE_VLAN_TAGGING VLAN_ID_Per_Frame_Info *vlan_pfi; Untagged_Attribute *untagged;#endif Last_Attribute *last; int tlv_length = 0; DEBUGLOG("bd_ans_AttributeFill: enter\n"); switch(attr_id) {#ifdef IANS_BASE_VLAN_TAGGING case IANS_ATTR_VLAN_ID: DEBUGLOG("bd_ans_AttributeFill: filling vlan id attr\n"); tlv_length = sizeof(VLAN_ID_Per_Frame_Info); vlan_pfi = (VLAN_ID_Per_Frame_Info *)pTLV; vlan_pfi->AttrHeader.AttributeID = IANS_ATTR_VLAN_ID; vlan_pfi->AttrHeader.AttributeLength = tlv_length - sizeof(Per_Frame_Attribute_Header); vlan_pfi->VLanID = *((UINT16 *)data); break; case IANS_ATTR_TAGGING_UNTAGGED: DEBUGLOG("bd_ans_AttributeFill: filling untagged attr\n"); tlv_length = sizeof(Untagged_Attribute); untagged = (Untagged_Attribute *)pTLV; untagged->AttrHeader.AttributeID = IANS_ATTR_TAGGING_UNTAGGED; untagged->AttrHeader.AttributeLength = tlv_length - sizeof(Per_Frame_Attribute_Header); break;#endif case IANS_ATTR_LAST_ATTR: DEBUGLOG("bd_ans_AttributeFill: filling last attr\n"); tlv_length = sizeof(Last_Attribute); last = (Last_Attribute *)pTLV; last->LastHeader.AttributeID = IANS_ATTR_LAST_ATTR; last->LastHeader.AttributeLength = 0; break; default: break; } return tlv_length;} /* bd_ans_ExtractValue()**** This function will extract the value from a TLV**** Arguments: Per_Frame_Attribute_Header *pTLV - pointer to the TLV**** Returns: UINT32 - dword value from the TLV. Smaller values ** should be cast correctly by the caller.*/UINT32bd_ans_ExtractValue(Per_Frame_Attribute_Header *pTLV){ UINT32 ret_val; UCHAR *p; p = (UCHAR *) &(pTLV->AttributeLength); p += sizeof(pTLV->AttributeLength); ret_val = *((UINT32 *)p); return (ret_val); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -