PHSModule.c 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612
  1. #include "headers.h"
  2. static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
  3. static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
  4. static UINT CreateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI);
  5. static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_ENTRY *pstClassifierEntry,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
  6. static BOOLEAN ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule);
  7. static BOOLEAN DerefPhsRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule);
  8. static UINT GetClassifierEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, S_CLASSIFIER_ENTRY **ppstClassifierEntry);
  9. static UINT GetPhsRuleEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,S_PHS_RULE **ppstPhsRule);
  10. static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable);
  11. static int phs_compress(S_PHS_RULE *phs_members,unsigned char *in_buf,
  12. unsigned char *out_buf,unsigned int *header_size,UINT *new_header_size );
  13. static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
  14. unsigned char *phsf,unsigned char *phsm,unsigned int phss,unsigned int phsv,UINT *new_header_size );
  15. static int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\
  16. S_PHS_RULE *phs_rules,UINT *header_size);
  17. static ULONG PhsCompress(void* pvContext,
  18. B_UINT16 uiVcid,
  19. B_UINT16 uiClsId,
  20. void *pvInputBuffer,
  21. void *pvOutputBuffer,
  22. UINT *pOldHeaderSize,
  23. UINT *pNewHeaderSize );
  24. static ULONG PhsDeCompress(void* pvContext,
  25. B_UINT16 uiVcid,
  26. void *pvInputBuffer,
  27. void *pvOutputBuffer,
  28. UINT *pInHeaderSize,
  29. UINT *pOutHeaderSize);
  30. #define IN
  31. #define OUT
  32. /*
  33. Function: PHSTransmit
  34. Description: This routine handle PHS(Payload Header Suppression for Tx path.
  35. It extracts a fragment of the NDIS_PACKET containing the header
  36. to be suppressed.It then supresses the header by invoking PHS exported compress routine.
  37. The header data after supression is copied back to the NDIS_PACKET.
  38. Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
  39. IN Packet - NDIS packet containing data to be transmitted
  40. IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to
  41. identify PHS rule to be applied.
  42. B_UINT16 uiClassifierRuleID - Classifier Rule ID
  43. BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF.
  44. Return: STATUS_SUCCESS - If the send was successful.
  45. Other - If an error occured.
  46. */
  47. int PHSTransmit(PMINI_ADAPTER Adapter,
  48. struct sk_buff **pPacket,
  49. USHORT Vcid,
  50. B_UINT16 uiClassifierRuleID,
  51. BOOLEAN bHeaderSuppressionEnabled,
  52. UINT *PacketLen,
  53. UCHAR bEthCSSupport)
  54. {
  55. //PHS Sepcific
  56. UINT unPHSPktHdrBytesCopied = 0;
  57. UINT unPhsOldHdrSize = 0;
  58. UINT unPHSNewPktHeaderLen = 0;
  59. /* Pointer to PHS IN Hdr Buffer */
  60. PUCHAR pucPHSPktHdrInBuf =
  61. Adapter->stPhsTxContextInfo.ucaHdrSupressionInBuf;
  62. /* Pointer to PHS OUT Hdr Buffer */
  63. PUCHAR pucPHSPktHdrOutBuf =
  64. Adapter->stPhsTxContextInfo.ucaHdrSupressionOutBuf;
  65. UINT usPacketType;
  66. UINT BytesToRemove=0;
  67. BOOLEAN bPHSI = 0;
  68. LONG ulPhsStatus = 0;
  69. UINT numBytesCompressed = 0;
  70. struct sk_buff *newPacket = NULL;
  71. struct sk_buff *Packet = *pPacket;
  72. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "In PHSTransmit");
  73. if(!bEthCSSupport)
  74. BytesToRemove=ETH_HLEN;
  75. /*
  76. Accumulate the header upto the size we support supression
  77. from NDIS packet
  78. */
  79. usPacketType=((struct ethhdr *)(Packet->data))->h_proto;
  80. pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
  81. //considering data after ethernet header
  82. if((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS)
  83. {
  84. unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove);
  85. }
  86. else
  87. {
  88. unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS;
  89. }
  90. if( (unPHSPktHdrBytesCopied > 0 ) &&
  91. (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS))
  92. {
  93. // Step 2 Supress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf.
  94. // Suppress only if IP Header and PHS Enabled For the Service Flow
  95. if(((usPacketType == ETHERNET_FRAMETYPE_IPV4) ||
  96. (usPacketType == ETHERNET_FRAMETYPE_IPV6)) &&
  97. (bHeaderSuppressionEnabled))
  98. {
  99. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nTrying to PHS Compress Using Classifier rule 0x%X",uiClassifierRuleID);
  100. unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied;
  101. ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext,
  102. Vcid,
  103. uiClassifierRuleID,
  104. pucPHSPktHdrInBuf,
  105. pucPHSPktHdrOutBuf,
  106. &unPhsOldHdrSize,
  107. &unPHSNewPktHeaderLen);
  108. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nPHS Old header Size : %d New Header Size %d\n",unPhsOldHdrSize,unPHSNewPktHeaderLen);
  109. if(unPHSNewPktHeaderLen == unPhsOldHdrSize)
  110. {
  111. if( ulPhsStatus == STATUS_PHS_COMPRESSED)
  112. bPHSI = *pucPHSPktHdrOutBuf;
  113. ulPhsStatus = STATUS_PHS_NOCOMPRESSION;
  114. }
  115. if( ulPhsStatus == STATUS_PHS_COMPRESSED)
  116. {
  117. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHS Sending packet Compressed");
  118. if(skb_cloned(Packet))
  119. {
  120. newPacket = skb_copy(Packet, GFP_ATOMIC);
  121. if(newPacket == NULL)
  122. return STATUS_FAILURE;
  123. dev_kfree_skb(Packet);
  124. *pPacket = Packet = newPacket;
  125. pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
  126. }
  127. numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN);
  128. memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
  129. memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
  130. skb_pull(Packet, numBytesCompressed);
  131. return STATUS_SUCCESS;
  132. }
  133. else
  134. {
  135. //if one byte headroom is not available, increase it through skb_cow
  136. if(!(skb_headroom(Packet) > 0))
  137. {
  138. if(skb_cow(Packet, 1))
  139. {
  140. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "SKB Cow Failed\n");
  141. return STATUS_FAILURE;
  142. }
  143. }
  144. skb_push(Packet, 1);
  145. // CAUTION: The MAC Header is getting corrupted here for IP CS - can be saved by copying 14 Bytes. not needed .... hence corrupting it.
  146. *(Packet->data + BytesToRemove) = bPHSI;
  147. return STATUS_SUCCESS;
  148. }
  149. }
  150. else
  151. {
  152. if(!bHeaderSuppressionEnabled)
  153. {
  154. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nHeader Suppression Disabled For SF: No PHS\n");
  155. }
  156. return STATUS_SUCCESS;
  157. }
  158. }
  159. //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHSTransmit : Dumping data packet After PHS");
  160. return STATUS_SUCCESS;
  161. }
  162. int PHSRecieve(PMINI_ADAPTER Adapter,
  163. USHORT usVcid,
  164. struct sk_buff *packet,
  165. UINT *punPacketLen,
  166. UCHAR *pucEthernetHdr,
  167. UINT bHeaderSuppressionEnabled)
  168. {
  169. u32 nStandardPktHdrLen = 0;
  170. u32 nTotalsupressedPktHdrBytes = 0;
  171. int ulPhsStatus = 0;
  172. PUCHAR pucInBuff = NULL ;
  173. UINT TotalBytesAdded = 0;
  174. if(!bHeaderSuppressionEnabled)
  175. {
  176. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nPhs Disabled for incoming packet");
  177. return ulPhsStatus;
  178. }
  179. pucInBuff = packet->data;
  180. //Restore PHS suppressed header
  181. nStandardPktHdrLen = packet->len;
  182. ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext,
  183. usVcid,
  184. pucInBuff,
  185. Adapter->ucaPHSPktRestoreBuf,
  186. &nTotalsupressedPktHdrBytes,
  187. &nStandardPktHdrLen);
  188. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nSupressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
  189. nTotalsupressedPktHdrBytes,nStandardPktHdrLen);
  190. if(ulPhsStatus != STATUS_PHS_COMPRESSED)
  191. {
  192. skb_pull(packet, 1);
  193. return STATUS_SUCCESS;
  194. }
  195. else
  196. {
  197. TotalBytesAdded = nStandardPktHdrLen - nTotalsupressedPktHdrBytes - PHSI_LEN;
  198. if(TotalBytesAdded)
  199. {
  200. if(skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded))
  201. skb_push(packet, TotalBytesAdded);
  202. else
  203. {
  204. if(skb_cow(packet, skb_headroom(packet) + TotalBytesAdded))
  205. {
  206. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "cow failed in receive\n");
  207. return STATUS_FAILURE;
  208. }
  209. skb_push(packet, TotalBytesAdded);
  210. }
  211. }
  212. memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen);
  213. }
  214. return STATUS_SUCCESS;
  215. }
  216. void DumpFullPacket(UCHAR *pBuf,UINT nPktLen)
  217. {
  218. PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
  219. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"Dumping Data Packet");
  220. BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,pBuf,nPktLen);
  221. }
  222. //-----------------------------------------------------------------------------
  223. // Procedure: phs_init
  224. //
  225. // Description: This routine is responsible for allocating memory for classifier and
  226. // PHS rules.
  227. //
  228. // Arguments:
  229. // pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules and PHS Rules , RX, TX buffer etc
  230. //
  231. // Returns:
  232. // TRUE(1) -If allocation of memory was success full.
  233. // FALSE -If allocation of memory fails.
  234. //-----------------------------------------------------------------------------
  235. int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter)
  236. {
  237. int i;
  238. S_SERVICEFLOW_TABLE *pstServiceFlowTable;
  239. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nPHS:phs_init function ");
  240. if(pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
  241. return -EINVAL;
  242. pPhsdeviceExtension->pstServiceFlowPhsRulesTable =
  243. kzalloc(sizeof(S_SERVICEFLOW_TABLE), GFP_KERNEL);
  244. if(!pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
  245. {
  246. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed");
  247. return -ENOMEM;
  248. }
  249. pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable;
  250. for(i=0;i<MAX_SERVICEFLOWS;i++)
  251. {
  252. S_SERVICEFLOW_ENTRY sServiceFlow = pstServiceFlowTable->stSFList[i];
  253. sServiceFlow.pstClassifierTable = kzalloc(sizeof(S_CLASSIFIER_TABLE), GFP_KERNEL);
  254. if(!sServiceFlow.pstClassifierTable)
  255. {
  256. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
  257. free_phs_serviceflow_rules(pPhsdeviceExtension->
  258. pstServiceFlowPhsRulesTable);
  259. pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
  260. return -ENOMEM;
  261. }
  262. }
  263. pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
  264. if(pPhsdeviceExtension->CompressedTxBuffer == NULL)
  265. {
  266. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
  267. free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
  268. pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
  269. return -ENOMEM;
  270. }
  271. pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
  272. if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL)
  273. {
  274. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
  275. kfree(pPhsdeviceExtension->CompressedTxBuffer);
  276. free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
  277. pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
  278. return -ENOMEM;
  279. }
  280. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successfull");
  281. return STATUS_SUCCESS;
  282. }
  283. int PhsCleanup(IN PPHS_DEVICE_EXTENSION pPHSDeviceExt)
  284. {
  285. if(pPHSDeviceExt->pstServiceFlowPhsRulesTable)
  286. {
  287. free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable);
  288. pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
  289. }
  290. kfree(pPHSDeviceExt->CompressedTxBuffer);
  291. pPHSDeviceExt->CompressedTxBuffer = NULL;
  292. kfree(pPHSDeviceExt->UnCompressedRxBuffer);
  293. pPHSDeviceExt->UnCompressedRxBuffer = NULL;
  294. return 0;
  295. }
  296. //PHS functions
  297. /*++
  298. PhsUpdateClassifierRule
  299. Routine Description:
  300. Exported function to add or modify a PHS Rule.
  301. Arguments:
  302. IN void* pvContext - PHS Driver Specific Context
  303. IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
  304. IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
  305. IN S_PHS_RULE *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table.
  306. Return Value:
  307. 0 if successful,
  308. >0 Error.
  309. --*/
  310. ULONG PhsUpdateClassifierRule(IN void* pvContext,
  311. IN B_UINT16 uiVcid ,
  312. IN B_UINT16 uiClsId ,
  313. IN S_PHS_RULE *psPhsRule,
  314. IN B_UINT8 u8AssociatedPHSI)
  315. {
  316. ULONG lStatus =0;
  317. UINT nSFIndex =0 ;
  318. S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
  319. PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
  320. PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
  321. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS With Corr2 Changes \n");
  322. if(pDeviceExtension == NULL)
  323. {
  324. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Invalid Device Extension\n");
  325. return ERR_PHS_INVALID_DEVICE_EXETENSION;
  326. }
  327. if(u8AssociatedPHSI == 0)
  328. {
  329. return ERR_PHS_INVALID_PHS_RULE;
  330. }
  331. /* Retrieve the SFID Entry Index for requested Service Flow */
  332. nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
  333. uiVcid,&pstServiceFlowEntry);
  334. if(nSFIndex == PHS_INVALID_TABLE_INDEX)
  335. {
  336. /* This is a new SF. Create a mapping entry for this */
  337. lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId,
  338. pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI);
  339. return lStatus;
  340. }
  341. /* SF already Exists Add PHS Rule to existing SF */
  342. lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId,
  343. pstServiceFlowEntry, psPhsRule, u8AssociatedPHSI);
  344. return lStatus;
  345. }
  346. /*++
  347. PhsDeletePHSRule
  348. Routine Description:
  349. Deletes the specified phs Rule within Vcid
  350. Arguments:
  351. IN void* pvContext - PHS Driver Specific Context
  352. IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
  353. IN B_UINT8 u8PHSI - the PHS Index identifying PHS rule to be deleted.
  354. Return Value:
  355. 0 if successful,
  356. >0 Error.
  357. --*/
  358. ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI)
  359. {
  360. ULONG lStatus =0;
  361. UINT nSFIndex =0, nClsidIndex =0 ;
  362. S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
  363. S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
  364. PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
  365. PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
  366. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n");
  367. if(pDeviceExtension)
  368. {
  369. //Retrieve the SFID Entry Index for requested Service Flow
  370. nSFIndex = GetServiceFlowEntry(pDeviceExtension
  371. ->pstServiceFlowPhsRulesTable,uiVcid,&pstServiceFlowEntry);
  372. if(nSFIndex == PHS_INVALID_TABLE_INDEX)
  373. {
  374. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
  375. return ERR_SF_MATCH_FAIL;
  376. }
  377. pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable;
  378. if(pstClassifierRulesTable)
  379. {
  380. for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++)
  381. {
  382. if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
  383. {
  384. if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) {
  385. if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
  386. pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
  387. if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
  388. kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
  389. memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0,
  390. sizeof(S_CLASSIFIER_ENTRY));
  391. }
  392. }
  393. }
  394. }
  395. }
  396. return lStatus;
  397. }
  398. /*++
  399. PhsDeleteClassifierRule
  400. Routine Description:
  401. Exported function to Delete a PHS Rule for the SFID,CLSID Pair.
  402. Arguments:
  403. IN void* pvContext - PHS Driver Specific Context
  404. IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
  405. IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
  406. Return Value:
  407. 0 if successful,
  408. >0 Error.
  409. --*/
  410. ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16 uiClsId)
  411. {
  412. ULONG lStatus =0;
  413. UINT nSFIndex =0, nClsidIndex =0 ;
  414. S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
  415. S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
  416. PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
  417. PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
  418. if(pDeviceExtension)
  419. {
  420. //Retrieve the SFID Entry Index for requested Service Flow
  421. nSFIndex = GetServiceFlowEntry(pDeviceExtension
  422. ->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry);
  423. if(nSFIndex == PHS_INVALID_TABLE_INDEX)
  424. {
  425. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"SFID Match Failed\n");
  426. return ERR_SF_MATCH_FAIL;
  427. }
  428. nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
  429. uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry);
  430. if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
  431. {
  432. if(pstClassifierEntry->pstPhsRule)
  433. {
  434. if(pstClassifierEntry->pstPhsRule->u8RefCnt)
  435. pstClassifierEntry->pstPhsRule->u8RefCnt--;
  436. if(0==pstClassifierEntry->pstPhsRule->u8RefCnt)
  437. kfree(pstClassifierEntry->pstPhsRule);
  438. }
  439. memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
  440. }
  441. nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
  442. uiClsId,eOldClassifierRuleContext,&pstClassifierEntry);
  443. if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
  444. {
  445. kfree(pstClassifierEntry->pstPhsRule);
  446. memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
  447. }
  448. }
  449. return lStatus;
  450. }
  451. /*++
  452. PhsDeleteSFRules
  453. Routine Description:
  454. Exported function to Delete a all PHS Rules for the SFID.
  455. Arguments:
  456. IN void* pvContext - PHS Driver Specific Context
  457. IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rules need to be deleted
  458. Return Value:
  459. 0 if successful,
  460. >0 Error.
  461. --*/
  462. ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid)
  463. {
  464. ULONG lStatus =0;
  465. UINT nSFIndex =0, nClsidIndex =0 ;
  466. S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
  467. S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
  468. PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
  469. PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
  470. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"====> \n");
  471. if(pDeviceExtension)
  472. {
  473. //Retrieve the SFID Entry Index for requested Service Flow
  474. nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
  475. uiVcid,&pstServiceFlowEntry);
  476. if(nSFIndex == PHS_INVALID_TABLE_INDEX)
  477. {
  478. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
  479. return ERR_SF_MATCH_FAIL;
  480. }
  481. pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable;
  482. if(pstClassifierRulesTable)
  483. {
  484. for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++)
  485. {
  486. if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
  487. {
  488. if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
  489. .pstPhsRule->u8RefCnt)
  490. pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
  491. .pstPhsRule->u8RefCnt--;
  492. if(0==pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
  493. .pstPhsRule->u8RefCnt)
  494. kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
  495. pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
  496. .pstPhsRule = NULL;
  497. }
  498. memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
  499. if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule)
  500. {
  501. if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
  502. .pstPhsRule->u8RefCnt)
  503. pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
  504. .pstPhsRule->u8RefCnt--;
  505. if(0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
  506. .pstPhsRule->u8RefCnt)
  507. kfree(pstClassifierRulesTable
  508. ->stOldPhsRulesList[nClsidIndex].pstPhsRule);
  509. pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
  510. .pstPhsRule = NULL;
  511. }
  512. memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
  513. }
  514. }
  515. pstServiceFlowEntry->bUsed = FALSE;
  516. pstServiceFlowEntry->uiVcid = 0;
  517. }
  518. return lStatus;
  519. }
  520. /*++
  521. PhsCompress
  522. Routine Description:
  523. Exported function to compress the data using PHS.
  524. Arguments:
  525. IN void* pvContext - PHS Driver Specific Context.
  526. IN B_UINT16 uiVcid - The Service Flow ID to which current packet header compression applies.
  527. IN UINT uiClsId - The Classifier ID to which current packet header compression applies.
  528. IN void *pvInputBuffer - The Input buffer containg packet header data
  529. IN void *pvOutputBuffer - The output buffer returned by this function after PHS
  530. IN UINT *pOldHeaderSize - The actual size of the header before PHS
  531. IN UINT *pNewHeaderSize - The new size of the header after applying PHS
  532. Return Value:
  533. 0 if successful,
  534. >0 Error.
  535. --*/
  536. ULONG PhsCompress(IN void* pvContext,
  537. IN B_UINT16 uiVcid,
  538. IN B_UINT16 uiClsId,
  539. IN void *pvInputBuffer,
  540. OUT void *pvOutputBuffer,
  541. OUT UINT *pOldHeaderSize,
  542. OUT UINT *pNewHeaderSize )
  543. {
  544. UINT nSFIndex =0, nClsidIndex =0 ;
  545. S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
  546. S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
  547. S_PHS_RULE *pstPhsRule = NULL;
  548. ULONG lStatus =0;
  549. PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
  550. PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
  551. if(pDeviceExtension == NULL)
  552. {
  553. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Invalid Device Extension\n");
  554. lStatus = STATUS_PHS_NOCOMPRESSION ;
  555. return lStatus;
  556. }
  557. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Suppressing header \n");
  558. //Retrieve the SFID Entry Index for requested Service Flow
  559. nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
  560. uiVcid,&pstServiceFlowEntry);
  561. if(nSFIndex == PHS_INVALID_TABLE_INDEX)
  562. {
  563. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"SFID Match Failed\n");
  564. lStatus = STATUS_PHS_NOCOMPRESSION ;
  565. return lStatus;
  566. }
  567. nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
  568. uiClsId,eActiveClassifierRuleContext,&pstClassifierEntry);
  569. if(nClsidIndex == PHS_INVALID_TABLE_INDEX)
  570. {
  571. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"No PHS Rule Defined For Classifier\n");
  572. lStatus = STATUS_PHS_NOCOMPRESSION ;
  573. return lStatus;
  574. }
  575. //get rule from SF id,Cls ID pair and proceed
  576. pstPhsRule = pstClassifierEntry->pstPhsRule;
  577. if(!ValidatePHSRuleComplete(pstPhsRule))
  578. {
  579. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS Rule Defined For Classifier But Not Complete\n");
  580. lStatus = STATUS_PHS_NOCOMPRESSION ;
  581. return lStatus;
  582. }
  583. //Compress Packet
  584. lStatus = phs_compress(pstPhsRule,(PUCHAR)pvInputBuffer,
  585. (PUCHAR)pvOutputBuffer, pOldHeaderSize,pNewHeaderSize);
  586. if(lStatus == STATUS_PHS_COMPRESSED)
  587. {
  588. pstPhsRule->PHSModifiedBytes += *pOldHeaderSize - *pNewHeaderSize - 1;
  589. pstPhsRule->PHSModifiedNumPackets++;
  590. }
  591. else
  592. pstPhsRule->PHSErrorNumPackets++;
  593. return lStatus;
  594. }
  595. /*++
  596. PhsDeCompress
  597. Routine Description:
  598. Exported function to restore the packet header in Rx path.
  599. Arguments:
  600. IN void* pvContext - PHS Driver Specific Context.
  601. IN B_UINT16 uiVcid - The Service Flow ID to which current packet header restoration applies.
  602. IN void *pvInputBuffer - The Input buffer containg suppressed packet header data
  603. OUT void *pvOutputBuffer - The output buffer returned by this function after restoration
  604. OUT UINT *pHeaderSize - The packet header size after restoration is returned in this parameter.
  605. Return Value:
  606. 0 if successful,
  607. >0 Error.
  608. --*/
  609. ULONG PhsDeCompress(IN void* pvContext,
  610. IN B_UINT16 uiVcid,
  611. IN void *pvInputBuffer,
  612. OUT void *pvOutputBuffer,
  613. OUT UINT *pInHeaderSize,
  614. OUT UINT *pOutHeaderSize )
  615. {
  616. UINT nSFIndex =0, nPhsRuleIndex =0 ;
  617. S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
  618. S_PHS_RULE *pstPhsRule = NULL;
  619. UINT phsi;
  620. PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
  621. PPHS_DEVICE_EXTENSION pDeviceExtension=
  622. (PPHS_DEVICE_EXTENSION)pvContext;
  623. *pInHeaderSize = 0;
  624. if(pDeviceExtension == NULL)
  625. {
  626. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Invalid Device Extension\n");
  627. return ERR_PHS_INVALID_DEVICE_EXETENSION;
  628. }
  629. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Restoring header \n");
  630. phsi = *((unsigned char *)(pvInputBuffer));
  631. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x \n",phsi);
  632. if(phsi == UNCOMPRESSED_PACKET )
  633. {
  634. return STATUS_PHS_NOCOMPRESSION;
  635. }
  636. //Retrieve the SFID Entry Index for requested Service Flow
  637. nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
  638. uiVcid,&pstServiceFlowEntry);
  639. if(nSFIndex == PHS_INVALID_TABLE_INDEX)
  640. {
  641. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n");
  642. return ERR_SF_MATCH_FAIL;
  643. }
  644. nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,phsi,
  645. eActiveClassifierRuleContext,&pstPhsRule);
  646. if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
  647. {
  648. //Phs Rule does not exist in active rules table. Lets try in the old rules table.
  649. nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,
  650. phsi,eOldClassifierRuleContext,&pstPhsRule);
  651. if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
  652. {
  653. return ERR_PHSRULE_MATCH_FAIL;
  654. }
  655. }
  656. *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer,
  657. (PUCHAR)pvOutputBuffer,pstPhsRule,pOutHeaderSize);
  658. pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1;
  659. pstPhsRule->PHSModifiedNumPackets++;
  660. return STATUS_PHS_COMPRESSED;
  661. }
  662. //-----------------------------------------------------------------------------
  663. // Procedure: free_phs_serviceflow_rules
  664. //
  665. // Description: This routine is responsible for freeing memory allocated for PHS rules.
  666. //
  667. // Arguments:
  668. // rules - ptr to S_SERVICEFLOW_TABLE structure.
  669. //
  670. // Returns:
  671. // Does not return any value.
  672. //-----------------------------------------------------------------------------
  673. static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
  674. {
  675. int i,j;
  676. PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
  677. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n");
  678. if(psServiceFlowRulesTable)
  679. {
  680. for(i=0;i<MAX_SERVICEFLOWS;i++)
  681. {
  682. S_SERVICEFLOW_ENTRY stServiceFlowEntry =
  683. psServiceFlowRulesTable->stSFList[i];
  684. S_CLASSIFIER_TABLE *pstClassifierRulesTable =
  685. stServiceFlowEntry.pstClassifierTable;
  686. if(pstClassifierRulesTable)
  687. {
  688. for(j=0;j<MAX_PHSRULE_PER_SF;j++)
  689. {
  690. if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule)
  691. {
  692. if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
  693. ->u8RefCnt)
  694. pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
  695. ->u8RefCnt--;
  696. if(0==pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
  697. ->u8RefCnt)
  698. kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule);
  699. pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL;
  700. }
  701. if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule)
  702. {
  703. if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
  704. ->u8RefCnt)
  705. pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
  706. ->u8RefCnt--;
  707. if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
  708. ->u8RefCnt)
  709. kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule);
  710. pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
  711. }
  712. }
  713. kfree(pstClassifierRulesTable);
  714. stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
  715. }
  716. }
  717. }
  718. kfree(psServiceFlowRulesTable);
  719. psServiceFlowRulesTable = NULL;
  720. }
  721. static BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule)
  722. {
  723. if(psPhsRule)
  724. {
  725. if(!psPhsRule->u8PHSI)
  726. {
  727. // PHSI is not valid
  728. return FALSE;
  729. }
  730. if(!psPhsRule->u8PHSS)
  731. {
  732. //PHSS Is Undefined
  733. return FALSE;
  734. }
  735. //Check if PHSF is defines for the PHS Rule
  736. if(!psPhsRule->u8PHSFLength) // If any part of PHSF is valid then Rule contains valid PHSF
  737. {
  738. return FALSE;
  739. }
  740. return TRUE;
  741. }
  742. else
  743. {
  744. return FALSE;
  745. }
  746. }
  747. UINT GetServiceFlowEntry(IN S_SERVICEFLOW_TABLE *psServiceFlowTable,
  748. IN B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry)
  749. {
  750. int i;
  751. for(i=0;i<MAX_SERVICEFLOWS;i++)
  752. {
  753. if(psServiceFlowTable->stSFList[i].bUsed)
  754. {
  755. if(psServiceFlowTable->stSFList[i].uiVcid == uiVcid)
  756. {
  757. *ppstServiceFlowEntry = &psServiceFlowTable->stSFList[i];
  758. return i;
  759. }
  760. }
  761. }
  762. *ppstServiceFlowEntry = NULL;
  763. return PHS_INVALID_TABLE_INDEX;
  764. }
  765. UINT GetClassifierEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
  766. IN B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
  767. OUT S_CLASSIFIER_ENTRY **ppstClassifierEntry)
  768. {
  769. int i;
  770. S_CLASSIFIER_ENTRY *psClassifierRules = NULL;
  771. for(i=0;i<MAX_PHSRULE_PER_SF;i++)
  772. {
  773. if(eClsContext == eActiveClassifierRuleContext)
  774. {
  775. psClassifierRules = &pstClassifierTable->stActivePhsRulesList[i];
  776. }
  777. else
  778. {
  779. psClassifierRules = &pstClassifierTable->stOldPhsRulesList[i];
  780. }
  781. if(psClassifierRules->bUsed)
  782. {
  783. if(psClassifierRules->uiClassifierRuleId == uiClsid)
  784. {
  785. *ppstClassifierEntry = psClassifierRules;
  786. return i;
  787. }
  788. }
  789. }
  790. *ppstClassifierEntry = NULL;
  791. return PHS_INVALID_TABLE_INDEX;
  792. }
  793. static UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
  794. IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
  795. OUT S_PHS_RULE **ppstPhsRule)
  796. {
  797. int i;
  798. S_CLASSIFIER_ENTRY *pstClassifierRule = NULL;
  799. for(i=0;i<MAX_PHSRULE_PER_SF;i++)
  800. {
  801. if(eClsContext == eActiveClassifierRuleContext)
  802. {
  803. pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[i];
  804. }
  805. else
  806. {
  807. pstClassifierRule = &pstClassifierTable->stOldPhsRulesList[i];
  808. }
  809. if(pstClassifierRule->bUsed)
  810. {
  811. if(pstClassifierRule->u8PHSI == uiPHSI)
  812. {
  813. *ppstPhsRule = pstClassifierRule->pstPhsRule;
  814. return i;
  815. }
  816. }
  817. }
  818. *ppstPhsRule = NULL;
  819. return PHS_INVALID_TABLE_INDEX;
  820. }
  821. UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid,IN B_UINT16 uiClsId,
  822. IN S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,
  823. B_UINT8 u8AssociatedPHSI)
  824. {
  825. S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
  826. UINT uiStatus = 0;
  827. int iSfIndex;
  828. BOOLEAN bFreeEntryFound =FALSE;
  829. //Check for a free entry in SFID table
  830. for(iSfIndex=0;iSfIndex < MAX_SERVICEFLOWS;iSfIndex++)
  831. {
  832. if(!psServiceFlowTable->stSFList[iSfIndex].bUsed)
  833. {
  834. bFreeEntryFound = TRUE;
  835. break;
  836. }
  837. }
  838. if(!bFreeEntryFound)
  839. return ERR_SFTABLE_FULL;
  840. psaClassifiertable = psServiceFlowTable->stSFList[iSfIndex].pstClassifierTable;
  841. uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,psPhsRule,
  842. eActiveClassifierRuleContext,u8AssociatedPHSI);
  843. if(uiStatus == PHS_SUCCESS)
  844. {
  845. //Add entry at free index to the SF
  846. psServiceFlowTable->stSFList[iSfIndex].bUsed = TRUE;
  847. psServiceFlowTable->stSFList[iSfIndex].uiVcid = uiVcid;
  848. }
  849. return uiStatus;
  850. }
  851. UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
  852. IN B_UINT16 uiClsId,IN S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,
  853. S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI)
  854. {
  855. S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
  856. UINT uiStatus =PHS_SUCCESS;
  857. UINT nClassifierIndex = 0;
  858. S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
  859. PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
  860. psaClassifiertable = pstServiceFlowEntry->pstClassifierTable;
  861. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "==>");
  862. /* Check if the supplied Classifier already exists */
  863. nClassifierIndex =GetClassifierEntry(
  864. pstServiceFlowEntry->pstClassifierTable,uiClsId,
  865. eActiveClassifierRuleContext,&pstClassifierEntry);
  866. if(nClassifierIndex == PHS_INVALID_TABLE_INDEX)
  867. {
  868. /*
  869. The Classifier doesn't exist. So its a new classifier being added.
  870. Add new entry to associate PHS Rule to the Classifier
  871. */
  872. uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,
  873. psPhsRule,eActiveClassifierRuleContext,u8AssociatedPHSI);
  874. return uiStatus;
  875. }
  876. /*
  877. The Classifier exists.The PHS Rule for this classifier
  878. is being modified
  879. */
  880. if(pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI)
  881. {
  882. if(pstClassifierEntry->pstPhsRule == NULL)
  883. return ERR_PHS_INVALID_PHS_RULE;
  884. /*
  885. This rule already exists if any fields are changed for this PHS
  886. rule update them.
  887. */
  888. /* If any part of PHSF is valid then we update PHSF */
  889. if(psPhsRule->u8PHSFLength)
  890. {
  891. //update PHSF
  892. memcpy(pstClassifierEntry->pstPhsRule->u8PHSF,
  893. psPhsRule->u8PHSF , MAX_PHS_LENGTHS);
  894. }
  895. if(psPhsRule->u8PHSFLength)
  896. {
  897. //update PHSFLen
  898. pstClassifierEntry->pstPhsRule->u8PHSFLength =
  899. psPhsRule->u8PHSFLength;
  900. }
  901. if(psPhsRule->u8PHSMLength)
  902. {
  903. //update PHSM
  904. memcpy(pstClassifierEntry->pstPhsRule->u8PHSM,
  905. psPhsRule->u8PHSM, MAX_PHS_LENGTHS);
  906. }
  907. if(psPhsRule->u8PHSMLength)
  908. {
  909. //update PHSM Len
  910. pstClassifierEntry->pstPhsRule->u8PHSMLength =
  911. psPhsRule->u8PHSMLength;
  912. }
  913. if(psPhsRule->u8PHSS)
  914. {
  915. //update PHSS
  916. pstClassifierEntry->pstPhsRule->u8PHSS = psPhsRule->u8PHSS;
  917. }
  918. //update PHSV
  919. pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV;
  920. }
  921. else
  922. {
  923. /*
  924. A new rule is being set for this classifier.
  925. */
  926. uiStatus=UpdateClassifierPHSRule( uiClsId, pstClassifierEntry,
  927. psaClassifiertable, psPhsRule, u8AssociatedPHSI);
  928. }
  929. return uiStatus;
  930. }
  931. static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
  932. S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
  933. E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI)
  934. {
  935. UINT iClassifierIndex = 0;
  936. BOOLEAN bFreeEntryFound = FALSE;
  937. S_CLASSIFIER_ENTRY *psClassifierRules = NULL;
  938. UINT nStatus = PHS_SUCCESS;
  939. PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
  940. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Inside CreateClassifierPHSRule");
  941. if(psaClassifiertable == NULL)
  942. {
  943. return ERR_INVALID_CLASSIFIERTABLE_FOR_SF;
  944. }
  945. if(eClsContext == eOldClassifierRuleContext)
  946. {
  947. /* If An Old Entry for this classifier ID already exists in the
  948. old rules table replace it. */
  949. iClassifierIndex =
  950. GetClassifierEntry(psaClassifiertable, uiClsId,
  951. eClsContext,&psClassifierRules);
  952. if(iClassifierIndex != PHS_INVALID_TABLE_INDEX)
  953. {
  954. /*
  955. The Classifier already exists in the old rules table
  956. Lets replace the old classifier with the new one.
  957. */
  958. bFreeEntryFound = TRUE;
  959. }
  960. }
  961. if(!bFreeEntryFound)
  962. {
  963. /*
  964. Continue to search for a free location to add the rule
  965. */
  966. for(iClassifierIndex = 0; iClassifierIndex <
  967. MAX_PHSRULE_PER_SF; iClassifierIndex++)
  968. {
  969. if(eClsContext == eActiveClassifierRuleContext)
  970. {
  971. psClassifierRules =
  972. &psaClassifiertable->stActivePhsRulesList[iClassifierIndex];
  973. }
  974. else
  975. {
  976. psClassifierRules =
  977. &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
  978. }
  979. if(!psClassifierRules->bUsed)
  980. {
  981. bFreeEntryFound = TRUE;
  982. break;
  983. }
  984. }
  985. }
  986. if(!bFreeEntryFound)
  987. {
  988. if(eClsContext == eActiveClassifierRuleContext)
  989. {
  990. return ERR_CLSASSIFIER_TABLE_FULL;
  991. }
  992. else
  993. {
  994. //Lets replace the oldest rule if we are looking in old Rule table
  995. if(psaClassifiertable->uiOldestPhsRuleIndex >=
  996. MAX_PHSRULE_PER_SF)
  997. {
  998. psaClassifiertable->uiOldestPhsRuleIndex =0;
  999. }
  1000. iClassifierIndex = psaClassifiertable->uiOldestPhsRuleIndex;
  1001. psClassifierRules =
  1002. &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
  1003. (psaClassifiertable->uiOldestPhsRuleIndex)++;
  1004. }
  1005. }
  1006. if(eClsContext == eOldClassifierRuleContext)
  1007. {
  1008. if(psClassifierRules->pstPhsRule == NULL)
  1009. {
  1010. psClassifierRules->pstPhsRule = kmalloc(sizeof(S_PHS_RULE),GFP_KERNEL);
  1011. if(NULL == psClassifierRules->pstPhsRule)
  1012. return ERR_PHSRULE_MEMALLOC_FAIL;
  1013. }
  1014. psClassifierRules->bUsed = TRUE;
  1015. psClassifierRules->uiClassifierRuleId = uiClsId;
  1016. psClassifierRules->u8PHSI = psPhsRule->u8PHSI;
  1017. psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule;
  1018. /* Update The PHS rule */
  1019. memcpy(psClassifierRules->pstPhsRule,
  1020. psPhsRule, sizeof(S_PHS_RULE));
  1021. }
  1022. else
  1023. {
  1024. nStatus = UpdateClassifierPHSRule(uiClsId,psClassifierRules,
  1025. psaClassifiertable,psPhsRule,u8AssociatedPHSI);
  1026. }
  1027. return nStatus;
  1028. }
  1029. static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
  1030. IN S_CLASSIFIER_ENTRY *pstClassifierEntry,
  1031. S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
  1032. B_UINT8 u8AssociatedPHSI)
  1033. {
  1034. S_PHS_RULE *pstAddPhsRule = NULL;
  1035. UINT nPhsRuleIndex = 0;
  1036. BOOLEAN bPHSRuleOrphaned = FALSE;
  1037. PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
  1038. psPhsRule->u8RefCnt =0;
  1039. /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry*/
  1040. bPHSRuleOrphaned = DerefPhsRule( uiClsId, psaClassifiertable,
  1041. pstClassifierEntry->pstPhsRule);
  1042. //Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF
  1043. nPhsRuleIndex =GetPhsRuleEntry(psaClassifiertable,u8AssociatedPHSI,
  1044. eActiveClassifierRuleContext, &pstAddPhsRule);
  1045. if(PHS_INVALID_TABLE_INDEX == nPhsRuleIndex)
  1046. {
  1047. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier");
  1048. if(psPhsRule->u8PHSI == 0)
  1049. {
  1050. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n");
  1051. return ERR_PHS_INVALID_PHS_RULE;
  1052. }
  1053. //Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId
  1054. if(FALSE == bPHSRuleOrphaned)
  1055. {
  1056. pstClassifierEntry->pstPhsRule = kmalloc(sizeof(S_PHS_RULE), GFP_KERNEL);
  1057. if(NULL == pstClassifierEntry->pstPhsRule)
  1058. {
  1059. return ERR_PHSRULE_MEMALLOC_FAIL;
  1060. }
  1061. }
  1062. memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE));
  1063. }
  1064. else
  1065. {
  1066. //Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule
  1067. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule");
  1068. if(bPHSRuleOrphaned)
  1069. {
  1070. kfree(pstClassifierEntry->pstPhsRule);
  1071. pstClassifierEntry->pstPhsRule = NULL;
  1072. }
  1073. pstClassifierEntry->pstPhsRule = pstAddPhsRule;
  1074. }
  1075. pstClassifierEntry->bUsed = TRUE;
  1076. pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI;
  1077. pstClassifierEntry->uiClassifierRuleId = uiClsId;
  1078. pstClassifierEntry->pstPhsRule->u8RefCnt++;
  1079. pstClassifierEntry->bUnclassifiedPHSRule = pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule;
  1080. return PHS_SUCCESS;
  1081. }
  1082. static BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule)
  1083. {
  1084. if(pstPhsRule==NULL)
  1085. return FALSE;
  1086. if(pstPhsRule->u8RefCnt)
  1087. pstPhsRule->u8RefCnt--;
  1088. if(0==pstPhsRule->u8RefCnt)
  1089. {
  1090. /*if(pstPhsRule->u8PHSI)
  1091. //Store the currently active rule into the old rules list
  1092. CreateClassifierPHSRule(uiClsId,psaClassifiertable,pstPhsRule,eOldClassifierRuleContext,pstPhsRule->u8PHSI);*/
  1093. return TRUE;
  1094. }
  1095. else
  1096. {
  1097. return FALSE;
  1098. }
  1099. }
  1100. void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension)
  1101. {
  1102. int i,j,k,l;
  1103. PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
  1104. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n Dumping PHS Rules : \n");
  1105. for(i=0;i<MAX_SERVICEFLOWS;i++)
  1106. {
  1107. S_SERVICEFLOW_ENTRY stServFlowEntry =
  1108. pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i];
  1109. if(stServFlowEntry.bUsed)
  1110. {
  1111. for(j=0;j<MAX_PHSRULE_PER_SF;j++)
  1112. {
  1113. for(l=0;l<2;l++)
  1114. {
  1115. S_CLASSIFIER_ENTRY stClsEntry;
  1116. if(l==0)
  1117. {
  1118. stClsEntry = stServFlowEntry.pstClassifierTable->stActivePhsRulesList[j];
  1119. if(stClsEntry.bUsed)
  1120. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Active PHS Rule : \n");
  1121. }
  1122. else
  1123. {
  1124. stClsEntry = stServFlowEntry.pstClassifierTable->stOldPhsRulesList[j];
  1125. if(stClsEntry.bUsed)
  1126. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Old PHS Rule : \n");
  1127. }
  1128. if(stClsEntry.bUsed)
  1129. {
  1130. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X",stServFlowEntry.uiVcid);
  1131. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X",stClsEntry.uiClassifierRuleId);
  1132. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X",stClsEntry.u8PHSI);
  1133. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n");
  1134. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X",stClsEntry.pstPhsRule->u8PHSI);
  1135. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ",stClsEntry.pstPhsRule->u8PHSFLength);
  1136. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : ");
  1137. for(k=0;k<stClsEntry.pstPhsRule->u8PHSFLength;k++)
  1138. {
  1139. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSF[k]);
  1140. }
  1141. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X",stClsEntry.pstPhsRule->u8PHSMLength);
  1142. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :");
  1143. for(k=0;k<stClsEntry.pstPhsRule->u8PHSMLength;k++)
  1144. {
  1145. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSM[k]);
  1146. }
  1147. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ",stClsEntry.pstPhsRule->u8PHSS);
  1148. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X",stClsEntry.pstPhsRule->u8PHSV);
  1149. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n");
  1150. }
  1151. }
  1152. }
  1153. }
  1154. }
  1155. }
  1156. //-----------------------------------------------------------------------------
  1157. // Procedure: phs_decompress
  1158. //
  1159. // Description: This routine restores the static fields within the packet.
  1160. //
  1161. // Arguments:
  1162. // in_buf - ptr to incoming packet buffer.
  1163. // out_buf - ptr to output buffer where the suppressed header is copied.
  1164. // decomp_phs_rules - ptr to PHS rule.
  1165. // header_size - ptr to field which holds the phss or phsf_length.
  1166. //
  1167. // Returns:
  1168. // size -The number of bytes of dynamic fields present with in the incoming packet
  1169. // header.
  1170. // 0 -If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed.
  1171. //-----------------------------------------------------------------------------
  1172. int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,
  1173. S_PHS_RULE *decomp_phs_rules,UINT *header_size)
  1174. {
  1175. int phss,size=0;
  1176. S_PHS_RULE *tmp_memb;
  1177. int bit,i=0;
  1178. unsigned char *phsf,*phsm;
  1179. int in_buf_len = *header_size-1;
  1180. PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
  1181. in_buf++;
  1182. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"====>\n");
  1183. *header_size = 0;
  1184. if((decomp_phs_rules == NULL ))
  1185. return 0;
  1186. tmp_memb = decomp_phs_rules;
  1187. //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi));
  1188. //*header_size = tmp_memb->u8PHSFLength;
  1189. phss = tmp_memb->u8PHSS;
  1190. phsf = tmp_memb->u8PHSF;
  1191. phsm = tmp_memb->u8PHSM;
  1192. if(phss > MAX_PHS_LENGTHS)
  1193. phss = MAX_PHS_LENGTHS;
  1194. //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI %d phss %d index %d",phsi,phss,index));
  1195. while((phss > 0) && (size < in_buf_len))
  1196. {
  1197. bit = ((*phsm << i)& SUPPRESS);
  1198. if(bit == SUPPRESS)
  1199. {
  1200. *out_buf = *phsf;
  1201. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d",
  1202. phss,*phsf,*out_buf);
  1203. }
  1204. else
  1205. {
  1206. *out_buf = *in_buf;
  1207. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d",
  1208. phss,*in_buf,*out_buf);
  1209. in_buf++;
  1210. size++;
  1211. }
  1212. out_buf++;
  1213. phsf++;
  1214. phss--;
  1215. i++;
  1216. *header_size=*header_size + 1;
  1217. if(i > MAX_NO_BIT)
  1218. {
  1219. i=0;
  1220. phsm++;
  1221. }
  1222. }
  1223. return size;
  1224. }
  1225. //-----------------------------------------------------------------------------
  1226. // Procedure: phs_compress
  1227. //
  1228. // Description: This routine suppresses the static fields within the packet.Before
  1229. // that it will verify the fields to be suppressed with the corresponding fields in the
  1230. // phsf. For verification it checks the phsv field of PHS rule. If set and verification
  1231. // succeeds it suppresses the field.If any one static field is found different none of
  1232. // the static fields are suppressed then the packet is sent as uncompressed packet with
  1233. // phsi=0.
  1234. //
  1235. // Arguments:
  1236. // phs_rule - ptr to PHS rule.
  1237. // in_buf - ptr to incoming packet buffer.
  1238. // out_buf - ptr to output buffer where the suppressed header is copied.
  1239. // header_size - ptr to field which holds the phss.
  1240. //
  1241. // Returns:
  1242. // size-The number of bytes copied into the output buffer i.e dynamic fields
  1243. // 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails.
  1244. //-----------------------------------------------------------------------------
  1245. static int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf
  1246. ,unsigned char *out_buf,UINT *header_size,UINT *new_header_size)
  1247. {
  1248. unsigned char *old_addr = out_buf;
  1249. int supress = 0;
  1250. PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
  1251. if(phs_rule == NULL)
  1252. {
  1253. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nphs_compress(): phs_rule null!");
  1254. *out_buf = ZERO_PHSI;
  1255. return STATUS_PHS_NOCOMPRESSION;
  1256. }
  1257. if(phs_rule->u8PHSS <= *new_header_size)
  1258. {
  1259. *header_size = phs_rule->u8PHSS;
  1260. }
  1261. else
  1262. {
  1263. *header_size = *new_header_size;
  1264. }
  1265. //To copy PHSI
  1266. out_buf++;
  1267. supress = verify_suppress_phsf(in_buf,out_buf,phs_rule->u8PHSF,
  1268. phs_rule->u8PHSM, phs_rule->u8PHSS, phs_rule->u8PHSV,new_header_size);
  1269. if(supress == STATUS_PHS_COMPRESSED)
  1270. {
  1271. *old_addr = (unsigned char)phs_rule->u8PHSI;
  1272. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress phsi %d",phs_rule->u8PHSI);
  1273. }
  1274. else
  1275. {
  1276. *old_addr = ZERO_PHSI;
  1277. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress PHSV Verification failed");
  1278. }
  1279. return supress;
  1280. }
  1281. //-----------------------------------------------------------------------------
  1282. // Procedure: verify_suppress_phsf
  1283. //
  1284. // Description: This routine verifies the fields of the packet and if all the
  1285. // static fields are equal it adds the phsi of that PHS rule.If any static
  1286. // field differs it woun't suppress any field.
  1287. //
  1288. // Arguments:
  1289. // rules_set - ptr to classifier_rules.
  1290. // in_buffer - ptr to incoming packet buffer.
  1291. // out_buffer - ptr to output buffer where the suppressed header is copied.
  1292. // phsf - ptr to phsf.
  1293. // phsm - ptr to phsm.
  1294. // phss - variable holding phss.
  1295. //
  1296. // Returns:
  1297. // size-The number of bytes copied into the output buffer i.e dynamic fields.
  1298. // 0 -Packet has failed the verification.
  1299. //-----------------------------------------------------------------------------
  1300. static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
  1301. unsigned char *phsf,unsigned char *phsm,unsigned int phss,
  1302. unsigned int phsv,UINT* new_header_size)
  1303. {
  1304. unsigned int size=0;
  1305. int bit,i=0;
  1306. PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
  1307. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf PHSM - 0x%X",*phsm);
  1308. if(phss>(*new_header_size))
  1309. {
  1310. phss=*new_header_size;
  1311. }
  1312. while(phss > 0)
  1313. {
  1314. bit = ((*phsm << i)& SUPPRESS);
  1315. if(bit == SUPPRESS)
  1316. {
  1317. if(*in_buffer != *phsf)
  1318. {
  1319. if(phsv == VERIFY)
  1320. {
  1321. 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);
  1322. return STATUS_PHS_NOCOMPRESSION;
  1323. }
  1324. }
  1325. else
  1326. 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);
  1327. }
  1328. else
  1329. {
  1330. *out_buffer = *in_buffer;
  1331. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In copying_header input %d out %d",*in_buffer,*out_buffer);
  1332. out_buffer++;
  1333. size++;
  1334. }
  1335. in_buffer++;
  1336. phsf++;
  1337. phss--;
  1338. i++;
  1339. if(i > MAX_NO_BIT)
  1340. {
  1341. i=0;
  1342. phsm++;
  1343. }
  1344. }
  1345. BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success");
  1346. *new_header_size = size;
  1347. return STATUS_PHS_COMPRESSED;
  1348. }