/*- * Copyright (c) 2003-2012 Broadcom Corporation * All Rights Reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ #ifndef __NLM_UCORE_H__ #define __NLM_UCORE_H__ /* Microcode registers */ #define UCORE_OUTBUF_DONE 0x8000 #define UCORE_RX_PKT_RDY 0x8004 #define UCORE_RX_PKT_INFO 0x8008 #define UCORE_CAM0 0x800c #define UCORE_CAM1 0x8010 #define UCORE_CAM2 0x8014 #define UCORE_CAM3 0x8018 #define UCORE_CAM_RESULT 0x801c #define UCORE_CSUMINFO 0x8020 #define UCORE_CRCINFO 0x8024 #define UCORE_CRCPOS 0x8028 #define UCORE_FR_FIFOEMPTY 0x802c #define UCORE_PKT_DISTR 0x8030 #define PACKET_MEMORY 0xFFE00 #define PACKET_DATA_OFFSET 64 #define SHARED_SCRATCH_MEM 0x18000 /* Distribution mode */ #define VAL_PDM(x) (((x) & 0x7) << 0) /* Dest distribution or distribution list */ #define VAL_DEST(x) (((x) & 0x3ff) << 8) #define VAL_PDL(x) (((x) & 0xf) << 4) /*output buffer done*/ #define VAL_FSV(x) (x << 19) #define VAL_FFS(x) (x << 14) #define FWD_DEST_ONLY 1 #define FWD_ENQ_DIST_VEC 2 #define FWD_ENQ_DEST 3 #define FWD_DIST_VEC 4 #define FWD_ENQ_DIST_VEC_SER 6 #define FWD_ENQ_DEST_SER 7 #define USE_HASH_DST (1 << 20) static __inline unsigned int nlm_read_ucore_reg(int reg) { volatile unsigned int *addr = (volatile void *)reg; return (*addr); } static __inline void nlm_write_ucore_reg(int reg, unsigned int val) { volatile unsigned int *addr = (volatile void *)reg; *addr = val; } #define NLM_DEFINE_UCORE(name, reg) \ static __inline unsigned int \ nlm_read_ucore_##name(void) \ { \ return nlm_read_ucore_reg(reg); \ } \ \ static __inline void \ nlm_write_ucore_##name(unsigned int v) \ { \ nlm_write_ucore_reg(reg, v); \ } struct __hack NLM_DEFINE_UCORE(obufdone, UCORE_OUTBUF_DONE); NLM_DEFINE_UCORE(rxpktrdy, UCORE_RX_PKT_RDY); NLM_DEFINE_UCORE(rxpktinfo, UCORE_RX_PKT_INFO); NLM_DEFINE_UCORE(cam0, UCORE_CAM0); NLM_DEFINE_UCORE(cam1, UCORE_CAM1); NLM_DEFINE_UCORE(cam2, UCORE_CAM2); NLM_DEFINE_UCORE(cam3, UCORE_CAM3); NLM_DEFINE_UCORE(camresult, UCORE_CAM_RESULT); NLM_DEFINE_UCORE(csuminfo, UCORE_CSUMINFO); NLM_DEFINE_UCORE(crcinfo, UCORE_CRCINFO); NLM_DEFINE_UCORE(crcpos, UCORE_CRCPOS); NLM_DEFINE_UCORE(freefifo_empty, UCORE_FR_FIFOEMPTY); NLM_DEFINE_UCORE(pktdistr, UCORE_PKT_DISTR); /* * l3cachelines - number of cache lines to allocate into l3 * fsv - 0 : use interface-id for selecting the free fifo pool * 1 : use free fifo pool selected by FFS field * ffs - selects which free fifo pool to use to take a free fifo * prepad_en - If this field is set to 1, part or all of the * 64 byte prepad seen by micro engines, is written * infront of every packet. * prepad_ovride - If this field is 1, the ucore system uses * prepad configuration defined in this register, * 0 means that it uses the configuration defined * in NAE RX_CONFIG register * prepad_size - number of 16 byte words in the 64-byte prepad * seen by micro engines and dma'ed to memory as * pkt prepad. This field is meaningful only if * prepad_en and prepad_ovride is set. * 0 : 1 word * 1 : 2 words * 2 : 3 words * 3 : 4 words * prepad[0-3]: writing 0 to this means that the 1st 16 byte offset * of prepad in micro engine, gets setup as prepad0/1/2/3. * prepad word. * 1 : means 2nd 16 byte chunk in prepad0/1/2/3 * 2 : means 3rd 16 byte chunk in prepad0/1/2/3 * 3 : means 4rth 16 byte chunk in prepad0/1/2/3 * pkt_discard - packet will be discarded if this is set to 1 * rd5 - value (single bit) to be inserted in bit 5, the unclassified * pkt bit of receive descriptor. If this bit is set, HPRE bit * should also be set in ucore_rxpktready register */ static __inline__ void nlm_ucore_pkt_done(int l3cachelines, int fsv, int ffs, int prepad_en, int prepad_ovride, int prepad_size, int prepad0, int prepad1, int prepad2, int prepad3, int pkt_discard, int rd5) { unsigned int val = 0; val |= ((l3cachelines & 0xfff) << 20); val |= ((fsv & 0x1) << 19); val |= ((ffs & 0x1f) << 14); val |= ((prepad_en & 0x1) << 3); val |= ((prepad_ovride & 0x1) << 2); val |= ((prepad_size & 0x3) << 12); val |= ((prepad0 & 0x3) << 4); val |= ((prepad1 & 0x3) << 6); val |= ((prepad2 & 0x3) << 8); val |= ((prepad3 & 0x3) << 10); val |= ((pkt_discard & 0x1) << 1); val |= ((rd5 & 0x1) << 0); nlm_write_ucore_obufdone(val); } /* Get the class full vector field from POE. * The POE maintains a threshold for each class. * A bit in this field will be set corresponding to the class approaching * class full status. */ static __inline__ int nlm_ucore_get_rxpkt_poeclassfullvec(unsigned int pktrdy) { return ((pktrdy >> 24) & 0xff); } /* This function returns 1 if the hardware parser extraction process * resulted in an error. Else, returns 0. */ static __inline__ int nlm_ucore_get_rxpkt_hwparsererr(unsigned int pktrdy) { return ((pktrdy >> 23) & 0x1); } /* This function returns the context number assigned to incoming * packet */ static __inline__ int nlm_ucore_get_rxpkt_context(unsigned int pktrdy) { return ((pktrdy >> 13) & 0x3ff); } /* this function returns the channel number of incoming packet, * and applies only to interlaken. */ static __inline__ int nlm_ucore_get_rxpkt_channel(unsigned int pktrdy) { return ((pktrdy >> 5) & 0xff); } /* This function returns the interface number on which the pkt * was received */ static __inline__ int nlm_ucore_get_rxpkt_interface(unsigned int pktrdy) { return (pktrdy & 0x1f); } /* This function returns 1 if end of packet (EOP) is set in * packet data. */ static __inline__ int nlm_ucore_get_rxpkt_eop(unsigned int rxpkt_info) { return ((rxpkt_info >> 9) & 0x1); } /* This function returns packet length of received pkt */ static __inline__ int nlm_ucore_get_rxpktlen(unsigned int rxpkt_info) { return (rxpkt_info & 0x1ff); } /* this function sets up the ucore TCAM keys. */ static __inline__ void nlm_ucore_setup_camkey(unsigned int cam_key0, unsigned int cam_key1, unsigned int cam_key2, unsigned int cam_key3) { nlm_write_ucore_cam0(cam_key0); nlm_write_ucore_cam1(cam_key1); nlm_write_ucore_cam2(cam_key2); nlm_write_ucore_cam3(cam_key3); } /* This function checks if the cam result is valid or not. * If valid, it returns the result, else it returns 0. */ static __inline__ int nlm_ucore_get_cam_result(unsigned int cam_result) { if (((cam_result >> 15) & 0x1) == 1) /* valid result */ return (cam_result & 0x3fff); return 0; } /* This function sets up the csum in ucore. * iphdr_start - defines the start of ip header (to check - is this byte * position???) * iphdr_len - This field is auto filled by h/w parser if zero, else * the value defined will be used. */ static __inline__ void nlm_ucore_csum_setup(int iphdr_start, int iphdr_len) { unsigned int val = 0; val |= ((iphdr_len & 0xff) << 8); val |= (iphdr_len & 0xff); nlm_write_ucore_csuminfo(val); } /* crcpos - position of crc in pkt. If crc position is within startcrc and * endcrc, zero out these bytes in the packet before computing crc. This * field is not needed for FCoE. * cps - If 1, uses the polynomial in RX_CRC_POLY1 of NAE register. * if 0, uses the polynomial in RX_CRC_POLY0 of NAE register. * fcoe - If this is 1, crc calculation starts from 'startCRC' and the CRC * engine ends calculation before the last byte. * cbm - if 1, enables crc byte mirroring, where bits within a byte will get * reversed (mirrored) during calculation of crc. * cfi - If 1, performs a final inversion of crc before comarison is done during * pkt reception. * startcrc - This field is always required for both FCoE and SCTP crc. * endcrc - This information needs to be setup only for SCTP. For FCoE this * information is provided by hardware. * valid - if set to 1, CRC status is placed into bit 2 of rx descriptor * if set to 0, TCP checksum status is placed into bit 2 of rx descriptor * keysize - defines the number of bytes in the pre-pad that contains the key */ static __inline__ void nlm_ucore_crc_setup(int crcpos, int cps, int cfi, int cbm, int fcoe, int keysize, int valid, int startcrc, int endcrc) { unsigned int val = 0; val |= ((cfi & 0x1) << 20); val |= ((cbm & 0x1) << 19); val |= ((fcoe & 0x1) << 18); val |= ((cps & 0x1) << 16); val |= (crcpos & 0xffff); nlm_write_ucore_crcpos(val); val = 0; val |= ((keysize & 0x3f) << 25); val |= ((valid & 0x1) << 24); val |= ((endcrc & 0xffff) << 8); val |= (startcrc & 0xff); nlm_write_ucore_crcinfo(val); } /* This function returns a fifo empty vector, where each bit provides * the status of a fifo pool, where if the pool is empty the bit gets * set to 1. */ static __inline__ int nlm_ucore_get_fifoempty(unsigned int fifoempty) { return (fifoempty & 0xfffff); } /* This function controls how POE will distribute the packet. * pdm - is the packet distribution mode, where * 0x0 - means packet distribution mode is not used * 0x1 - means forwarding based on destination only (no enqueue) * 0x2 - means forwarding based on FID and distr vector (enqueue) * 0x3 - means forwarding based on dest and FID (enqueue) * 0x4 - means forwarding based on distr vec (no enqueue) * 0x6 - means forward based on FID (enqueue), distr vec and serial mode * 0x7 - means forward based on FID (enqueue), dest and serial mode * mc3 - If 1, then the 3 most significant bits of distribution list are taken * from context->class_table * pdl - poe distribution list * dest - fixed destination setup * hash - if 1, use hash based destination */ static __inline__ void nlm_ucore_setup_poepktdistr(int pdm, int mc3, int pdl, int dest, int hash) { unsigned int val = 0; val |= ((hash & 0x1) << 20); val |= ((dest & 0xfff) << 8); val |= ((pdl & 0xf) << 4); val |= ((mc3 & 0x1) << 3); val |= (pdm & 0x7); nlm_write_ucore_pktdistr(val); } #endif