Path: blob/main/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_prs.c
48524 views
/*1* Copyright 2008-2012 Freescale Semiconductor Inc.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions are met:5* * Redistributions of source code must retain the above copyright6* notice, this list of conditions and the following disclaimer.7* * Redistributions in binary form must reproduce the above copyright8* notice, this list of conditions and the following disclaimer in the9* documentation and/or other materials provided with the distribution.10* * Neither the name of Freescale Semiconductor nor the11* names of its contributors may be used to endorse or promote products12* derived from this software without specific prior written permission.13*14*15* ALTERNATIVELY, this software may be distributed under the terms of the16* GNU General Public License ("GPL") as published by the Free Software17* Foundation, either version 2 of that License or (at your option) any18* later version.19*20* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY21* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED22* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE23* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY24* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES25* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;26* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND27* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT28* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS29* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.30*/313233/******************************************************************************34@File fm_pcd.c3536@Description FM PCD ...37*//***************************************************************************/38#include <linux/math64.h>39#include "std_ext.h"40#include "error_ext.h"41#include "string_ext.h"42#include "debug_ext.h"43#include "net_ext.h"4445#include "fm_common.h"46#include "fm_pcd.h"47#include "fm_pcd_ipc.h"48#include "fm_prs.h"49#include "fsl_fman_prs.h"505152static void PcdPrsErrorException(t_Handle h_FmPcd)53{54t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;55uint32_t event, ev_mask;56struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;5758ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);59ev_mask = fman_prs_get_err_ev_mask(PrsRegs);6061event = fman_prs_get_err_event(PrsRegs, ev_mask);6263fman_prs_ack_err_event(PrsRegs, event);6465DBG(TRACE, ("parser error - 0x%08x\n",event));6667if(event & FM_PCD_PRS_DOUBLE_ECC)68p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC);69}7071static void PcdPrsException(t_Handle h_FmPcd)72{73t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;74uint32_t event, ev_mask;75struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;7677ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);78ev_mask = fman_prs_get_expt_ev_mask(PrsRegs);79event = fman_prs_get_expt_event(PrsRegs, ev_mask);8081ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC);8283DBG(TRACE, ("parser event - 0x%08x\n",event));8485fman_prs_ack_expt_event(PrsRegs, event);8687p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);88}8990t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams)91{92t_FmPcdPrs *p_FmPcdPrs;93uintptr_t baseAddr;9495UNUSED(p_FmPcd);96UNUSED(p_FmPcdParams);9798p_FmPcdPrs = (t_FmPcdPrs *) XX_Malloc(sizeof(t_FmPcdPrs));99if (!p_FmPcdPrs)100{101REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Parser structure allocation FAILED"));102return NULL;103}104memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs));105fman_prs_defconfig(&p_FmPcd->p_FmPcdDriverParam->dfltCfg);106107if (p_FmPcd->guestId == NCSW_MASTER_ID)108{109baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm);110p_FmPcdPrs->p_SwPrsCode = (uint32_t *)UINT_TO_PTR(baseAddr);111p_FmPcdPrs->p_FmPcdPrsRegs = (struct fman_prs_regs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET);112}113114p_FmPcdPrs->fmPcdPrsPortIdStatistics = p_FmPcd->p_FmPcdDriverParam->dfltCfg.port_id_stat;115p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = p_FmPcd->p_FmPcdDriverParam->dfltCfg.max_prs_cyc_lim;116p_FmPcd->exceptions |= p_FmPcd->p_FmPcdDriverParam->dfltCfg.prs_exceptions;117118return p_FmPcdPrs;119}120121#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))122static uint8_t swPrsPatch[] = SW_PRS_UDP_LITE_PATCH;123#else124static uint8_t swPrsPatch[] = SW_PRS_OFFLOAD_PATCH;125#endif /* FM_CAPWAP_SUPPORT */126127t_Error PrsInit(t_FmPcd *p_FmPcd)128{129t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;130uint32_t *p_TmpCode;131uint32_t *p_LoadTarget = (uint32_t *)PTR_MOVE(p_FmPcd->p_FmPcdPrs->p_SwPrsCode,132FM_PCD_SW_PRS_SIZE-FM_PCD_PRS_SW_PATCHES_SIZE);133struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;134uint32_t i;135136ASSERT_COND(sizeof(swPrsPatch) <= (FM_PCD_PRS_SW_PATCHES_SIZE-FM_PCD_PRS_SW_TAIL_SIZE));137138/* nothing to do in guest-partition */139if (p_FmPcd->guestId != NCSW_MASTER_ID)140return E_OK;141142p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(sizeof(swPrsPatch),4), 0, sizeof(uint32_t));143if (!p_TmpCode)144RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));145memset((uint8_t *)p_TmpCode, 0, ROUND_UP(sizeof(swPrsPatch),4));146memcpy((uint8_t *)p_TmpCode, (uint8_t *)swPrsPatch, sizeof(swPrsPatch));147148fman_prs_init(PrsRegs, &p_Param->dfltCfg);149150/* register even if no interrupts enabled, to allow future enablement */151FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd);152153/* register even if no interrupts enabled, to allow future enablement */154FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd);155156if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)157FmEnableRamsEcc(p_FmPcd->h_Fm);158159if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)160FmEnableRamsEcc(p_FmPcd->h_Fm);161162/* load sw parser Ip-Frag patch */163for (i=0; i<DIV_CEIL(sizeof(swPrsPatch), 4); i++)164WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));165166XX_FreeSmart(p_TmpCode);167168return E_OK;169}170171void PrsFree(t_FmPcd *p_FmPcd)172{173ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);174FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR);175/* register even if no interrupts enabled, to allow future enablement */176FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL);177}178179void PrsEnable(t_FmPcd *p_FmPcd)180{181struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;182183ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);184fman_prs_enable(PrsRegs);185}186187void PrsDisable(t_FmPcd *p_FmPcd)188{189struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;190191ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);192fman_prs_disable(PrsRegs);193}194195int PrsIsEnabled(t_FmPcd *p_FmPcd)196{197struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;198199ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);200return fman_prs_is_enabled(PrsRegs);201}202203t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include)204{205struct fman_prs_regs *PrsRegs;206uint32_t bitMask = 0;207uint8_t prsPortId;208209SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);210SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);211SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);212213PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;214215GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId);216GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId);217218if (include)219p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask;220else221p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask;222223fman_prs_set_stst_port_msk(PrsRegs,224p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);225226return E_OK;227}228229t_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include)230{231t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;232t_Error err;233234SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);235SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);236SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);237238if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&239p_FmPcd->h_IpcSession)240{241t_FmPcdIpcPrsIncludePort prsIncludePortParams;242t_FmPcdIpcMsg msg;243244prsIncludePortParams.hardwarePortId = hardwarePortId;245prsIncludePortParams.include = include;246memset(&msg, 0, sizeof(msg));247msg.msgId = FM_PCD_PRS_INC_PORT_STATS;248memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams));249err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,250(uint8_t*)&msg,251sizeof(msg.msgId) +sizeof(prsIncludePortParams),252NULL,253NULL,254NULL,255NULL);256if (err != E_OK)257RETURN_ERROR(MAJOR, err, NO_MSG);258return E_OK;259}260else if (p_FmPcd->guestId != NCSW_MASTER_ID)261RETURN_ERROR(MINOR, E_NOT_SUPPORTED,262("running in guest-mode without IPC!"));263264return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include);265}266267uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr)268{269t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;270t_FmPcdPrsLabelParams *p_Label;271int i;272273SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0);274SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE, 0);275276if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&277p_FmPcd->h_IpcSession)278{279t_Error err = E_OK;280t_FmPcdIpcSwPrsLable labelParams;281t_FmPcdIpcMsg msg;282uint32_t prsOffset = 0;283t_FmPcdIpcReply reply;284uint32_t replyLength;285286memset(&reply, 0, sizeof(reply));287memset(&msg, 0, sizeof(msg));288labelParams.enumHdr = (uint32_t)hdr;289labelParams.indexPerHdr = indexPerHdr;290msg.msgId = FM_PCD_GET_SW_PRS_OFFSET;291memcpy(msg.msgBody, &labelParams, sizeof(labelParams));292replyLength = sizeof(uint32_t) + sizeof(uint32_t);293err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,294(uint8_t*)&msg,295sizeof(msg.msgId) +sizeof(labelParams),296(uint8_t*)&reply,297&replyLength,298NULL,299NULL);300if (err != E_OK)301RETURN_ERROR(MAJOR, err, NO_MSG);302if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))303RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));304305memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t));306return prsOffset;307}308else if (p_FmPcd->guestId != NCSW_MASTER_ID)309RETURN_ERROR(MINOR, E_NOT_SUPPORTED,310("running in guest-mode without IPC!"));311312ASSERT_COND(p_FmPcd->p_FmPcdPrs->currLabel < FM_PCD_PRS_NUM_OF_LABELS);313314for (i=0; i<p_FmPcd->p_FmPcdPrs->currLabel; i++)315{316p_Label = &p_FmPcd->p_FmPcdPrs->labelsTable[i];317318if ((hdr == p_Label->hdr) && (indexPerHdr == p_Label->indexPerHdr))319return p_Label->instructionOffset;320}321322REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Sw Parser attachment Not found"));323return (uint32_t)ILLEGAL_BASE;324}325326void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable)327{328t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;329struct fman_prs_regs *PrsRegs;330331SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);332SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);333334PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;335336337if(p_FmPcd->guestId != NCSW_MASTER_ID)338{339REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPrsStatistics - guest mode!"));340return;341}342343fman_prs_set_stst(PrsRegs, enable);344}345346t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs)347{348t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;349uint32_t *p_LoadTarget;350uint32_t *p_TmpCode;351int i;352353SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);354SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);355SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_STATE);356SANITY_CHECK_RETURN_ERROR(p_SwPrs, E_INVALID_HANDLE);357SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_HANDLE);358359if (p_FmPcd->guestId != NCSW_MASTER_ID)360RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode!"));361362if (!p_SwPrs->override)363{364if(p_FmPcd->p_FmPcdPrs->p_CurrSwPrs > p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4)365RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SW parser base must be larger than current loaded code"));366}367else368p_FmPcd->p_FmPcdPrs->currLabel = 0;369370if (p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2)371RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size may not be larger than MAX_SW_PRS_CODE_SIZE"));372373if (p_FmPcd->p_FmPcdPrs->currLabel + p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS)374RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed "));375376p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(p_SwPrs->size,4), 0, sizeof(uint32_t));377if (!p_TmpCode)378RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));379memset((uint8_t *)p_TmpCode, 0, ROUND_UP(p_SwPrs->size,4));380memcpy((uint8_t *)p_TmpCode, p_SwPrs->p_Code, p_SwPrs->size);381382/* save sw parser labels */383memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel],384p_SwPrs->labelsTable,385p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams));386p_FmPcd->p_FmPcdPrs->currLabel += p_SwPrs->numOfLabels;387388/* load sw parser code */389p_LoadTarget = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4;390391for(i=0; i<DIV_CEIL(p_SwPrs->size, 4); i++)392WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));393394p_FmPcd->p_FmPcdPrs->p_CurrSwPrs =395p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + ROUND_UP(p_SwPrs->size,4);396397/* copy data parameters */398for (i=0;i<FM_PCD_PRS_NUM_OF_HDRS;i++)399WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+PRS_SW_DATA/4+i), p_SwPrs->swPrsDataParams[i]);400401/* Clear last 4 bytes */402WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+(PRS_SW_DATA-FM_PCD_PRS_SW_TAIL_SIZE)/4), 0);403404XX_FreeSmart(p_TmpCode);405406return E_OK;407}408409t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value)410{411t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;412413SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);414SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);415416if(p_FmPcd->guestId != NCSW_MASTER_ID)417RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPrsMaxCycleLimit - guest mode!"));418419p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = value;420421return E_OK;422}423424425