/* * Copyright 2015-2016 Freescale Semiconductor, Inc. * Copyright 2017 NXP * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef _PFE_HIF_H_ #define _PFE_HIF_H_ #include #define HIF_NAPI_STATS #define HIF_CLIENT_QUEUES_MAX 16 #define HIF_RX_POLL_WEIGHT 64 #define HIF_RX_PKT_MIN_SIZE 0x800 /* 2KB */ #define HIF_RX_PKT_MIN_SIZE_MASK ~(HIF_RX_PKT_MIN_SIZE - 1) #define ROUND_MIN_RX_SIZE(_sz) (((_sz) + (HIF_RX_PKT_MIN_SIZE - 1)) \ & HIF_RX_PKT_MIN_SIZE_MASK) #define PRESENT_OFST_IN_PAGE(_buf) (((unsigned long int)(_buf) & (PAGE_SIZE \ - 1)) & HIF_RX_PKT_MIN_SIZE_MASK) enum { NAPI_SCHED_COUNT = 0, NAPI_POLL_COUNT, NAPI_PACKET_COUNT, NAPI_DESC_COUNT, NAPI_FULL_BUDGET_COUNT, NAPI_CLIENT_FULL_COUNT, NAPI_MAX_COUNT }; /* * HIF_TX_DESC_NT value should be always greter than 4, * Otherwise HIF_TX_POLL_MARK will become zero. */ #define HIF_RX_DESC_NT 256 #define HIF_TX_DESC_NT 2048 #define HIF_FIRST_BUFFER BIT(0) #define HIF_LAST_BUFFER BIT(1) #define HIF_DONT_DMA_MAP BIT(2) #define HIF_DATA_VALID BIT(3) #define HIF_TSO BIT(4) enum { PFE_CL_GEM0 = 0, PFE_CL_GEM1, HIF_CLIENTS_MAX }; /*structure to store client queue info */ struct hif_rx_queue { struct rx_queue_desc *base; u32 size; u32 write_idx; }; struct hif_tx_queue { struct tx_queue_desc *base; u32 size; u32 ack_idx; }; /*Structure to store the client info */ struct hif_client { int rx_qn; struct hif_rx_queue rx_q[HIF_CLIENT_QUEUES_MAX]; int tx_qn; struct hif_tx_queue tx_q[HIF_CLIENT_QUEUES_MAX]; }; /*HIF hardware buffer descriptor */ struct hif_desc { u32 ctrl; u32 status; u32 data; u32 next; }; struct __hif_desc { u32 ctrl; u32 status; u32 data; }; struct hif_desc_sw { dma_addr_t data; u16 len; u8 client_id; u8 q_no; u16 flags; }; struct hif_hdr { u8 client_id; u8 q_num; u16 client_ctrl; u16 client_ctrl1; }; struct __hif_hdr { union { struct hif_hdr hdr; u32 word[2]; }; }; struct hif_ipsec_hdr { u16 sa_handle[2]; } __packed; /* HIF_CTRL_TX... defines */ #define HIF_CTRL_TX_CHECKSUM BIT(2) /* HIF_CTRL_RX... defines */ #define HIF_CTRL_RX_OFFSET_OFST (24) #define HIF_CTRL_RX_CHECKSUMMED BIT(2) #define HIF_CTRL_RX_CONTINUED BIT(1) struct pfe_hif { /* To store registered clients in hif layer */ struct hif_client client[HIF_CLIENTS_MAX]; struct hif_shm *shm; int irq; void *descr_baseaddr_v; unsigned long descr_baseaddr_p; struct hif_desc *rx_base; u32 rx_ring_size; u32 rxtoclean_index; void *rx_buf_addr[HIF_RX_DESC_NT]; int rx_buf_len[HIF_RX_DESC_NT]; unsigned int qno; unsigned int client_id; unsigned int client_ctrl; unsigned int started; struct hif_desc *tx_base; u32 tx_ring_size; u32 txtosend; u32 txtoclean; u32 txavail; u32 txtoflush; struct hif_desc_sw tx_sw_queue[HIF_TX_DESC_NT]; /* tx_lock synchronizes hif packet tx as well as pfe_hif structure access */ spinlock_t tx_lock; /* lock synchronizes hif rx queue processing */ spinlock_t lock; struct net_device dummy_dev; struct napi_struct napi; struct device *dev; #ifdef HIF_NAPI_STATS unsigned int napi_counters[NAPI_MAX_COUNT]; #endif struct tasklet_struct tx_cleanup_tasklet; }; void __hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no, void *data, u32 len, unsigned int flags); int hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no, void *data, unsigned int len); void __hif_tx_done_process(struct pfe_hif *hif, int count); void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int data2); int pfe_hif_init(struct pfe *pfe); void pfe_hif_exit(struct pfe *pfe); void pfe_hif_rx_idle(struct pfe_hif *hif); static inline void hif_tx_done_process(struct pfe_hif *hif, int count) { spin_lock_bh(&hif->tx_lock); __hif_tx_done_process(hif, count); spin_unlock_bh(&hif->tx_lock); } static inline void hif_tx_lock(struct pfe_hif *hif) { spin_lock_bh(&hif->tx_lock); } static inline void hif_tx_unlock(struct pfe_hif *hif) { spin_unlock_bh(&hif->tx_lock); } static inline int __hif_tx_avail(struct pfe_hif *hif) { return hif->txavail; } #define __memcpy8(dst, src) memcpy(dst, src, 8) #define __memcpy12(dst, src) memcpy(dst, src, 12) #define __memcpy(dst, src, len) memcpy(dst, src, len) #endif /* _PFE_HIF_H_ */