0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifndef __LIBCXGB_PPM_H__
0038 #define __LIBCXGB_PPM_H__
0039
0040 #include <linux/kernel.h>
0041 #include <linux/errno.h>
0042 #include <linux/types.h>
0043 #include <linux/debugfs.h>
0044 #include <linux/list.h>
0045 #include <linux/netdevice.h>
0046 #include <linux/scatterlist.h>
0047 #include <linux/skbuff.h>
0048 #include <linux/vmalloc.h>
0049 #include <linux/bitmap.h>
0050
0051 struct cxgbi_pagepod_hdr {
0052 u32 vld_tid;
0053 u32 pgsz_tag_clr;
0054 u32 max_offset;
0055 u32 page_offset;
0056 u64 rsvd;
0057 };
0058
0059 #define PPOD_PAGES_MAX 4
0060 struct cxgbi_pagepod {
0061 struct cxgbi_pagepod_hdr hdr;
0062 __be64 addr[PPOD_PAGES_MAX + 1];
0063 };
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 #define DDP_PGIDX_MAX 4
0081 #define DDP_PGSZ_BASE_SHIFT 12
0082
0083 struct cxgbi_task_tag_info {
0084 unsigned char flags;
0085 #define CXGBI_PPOD_INFO_FLAG_VALID 0x1
0086 #define CXGBI_PPOD_INFO_FLAG_MAPPED 0x2
0087 unsigned char cid;
0088 unsigned short pg_shift;
0089 unsigned int npods;
0090 unsigned int idx;
0091 unsigned int tag;
0092 struct cxgbi_pagepod_hdr hdr;
0093 int nents;
0094 int nr_pages;
0095 struct scatterlist *sgl;
0096 };
0097
0098 struct cxgbi_tag_format {
0099 unsigned char pgsz_order[DDP_PGIDX_MAX];
0100 unsigned char pgsz_idx_dflt;
0101 unsigned char free_bits:4;
0102 unsigned char color_bits:4;
0103 unsigned char idx_bits;
0104 unsigned char rsvd_bits;
0105 unsigned int no_ddp_mask;
0106 unsigned int idx_mask;
0107 unsigned int color_mask;
0108 unsigned int idx_clr_mask;
0109 unsigned int rsvd_mask;
0110 };
0111
0112 struct cxgbi_ppod_data {
0113 unsigned char pg_idx:2;
0114 unsigned char color:6;
0115 unsigned char chan_id;
0116 unsigned short npods;
0117 unsigned long caller_data;
0118 };
0119
0120
0121 struct cxgbi_ppm_pool {
0122 unsigned int base;
0123 unsigned int next;
0124 spinlock_t lock;
0125 unsigned long bmap[];
0126 } ____cacheline_aligned_in_smp;
0127
0128 struct cxgbi_ppm {
0129 struct kref refcnt;
0130 struct net_device *ndev;
0131 struct pci_dev *pdev;
0132 void *lldev;
0133 void **ppm_pp;
0134 struct cxgbi_tag_format tformat;
0135 unsigned int ppmax;
0136 unsigned int llimit;
0137 unsigned int base_idx;
0138
0139 unsigned int pool_rsvd;
0140 unsigned int pool_index_max;
0141 struct cxgbi_ppm_pool __percpu *pool;
0142
0143 spinlock_t map_lock;
0144 unsigned int bmap_index_max;
0145 unsigned int next;
0146 unsigned int max_index_in_edram;
0147 unsigned long *ppod_bmap;
0148 struct cxgbi_ppod_data ppod_data[];
0149 };
0150
0151 #define DDP_THRESHOLD 512
0152
0153 #define PPOD_PAGES_SHIFT 2
0154
0155 #define IPPOD_SIZE sizeof(struct cxgbi_pagepod)
0156 #define PPOD_SIZE_SHIFT 6
0157
0158
0159 #define PPOD_CLUSTER_SIZE 16U
0160
0161 #define ULPMEM_DSGL_MAX_NPPODS 16
0162 #define ULPMEM_IDATA_MAX_NPPODS 3
0163 #define PCIE_MEMWIN_MAX_NPPODS 16
0164
0165 #define PPOD_COLOR_SHIFT 0
0166 #define PPOD_COLOR(x) ((x) << PPOD_COLOR_SHIFT)
0167
0168 #define PPOD_IDX_SHIFT 6
0169 #define PPOD_IDX_MAX_SIZE 24
0170
0171 #define PPOD_TID_SHIFT 0
0172 #define PPOD_TID(x) ((x) << PPOD_TID_SHIFT)
0173
0174 #define PPOD_TAG_SHIFT 6
0175 #define PPOD_TAG(x) ((x) << PPOD_TAG_SHIFT)
0176
0177 #define PPOD_VALID_SHIFT 24
0178 #define PPOD_VALID(x) ((x) << PPOD_VALID_SHIFT)
0179 #define PPOD_VALID_FLAG PPOD_VALID(1U)
0180
0181 #define PPOD_PI_EXTRACT_CTL_SHIFT 31
0182 #define PPOD_PI_EXTRACT_CTL(x) ((x) << PPOD_PI_EXTRACT_CTL_SHIFT)
0183 #define PPOD_PI_EXTRACT_CTL_FLAG V_PPOD_PI_EXTRACT_CTL(1U)
0184
0185 #define PPOD_PI_TYPE_SHIFT 29
0186 #define PPOD_PI_TYPE_MASK 0x3
0187 #define PPOD_PI_TYPE(x) ((x) << PPOD_PI_TYPE_SHIFT)
0188
0189 #define PPOD_PI_CHECK_CTL_SHIFT 27
0190 #define PPOD_PI_CHECK_CTL_MASK 0x3
0191 #define PPOD_PI_CHECK_CTL(x) ((x) << PPOD_PI_CHECK_CTL_SHIFT)
0192
0193 #define PPOD_PI_REPORT_CTL_SHIFT 25
0194 #define PPOD_PI_REPORT_CTL_MASK 0x3
0195 #define PPOD_PI_REPORT_CTL(x) ((x) << PPOD_PI_REPORT_CTL_SHIFT)
0196
0197 static inline int cxgbi_ppm_is_ddp_tag(struct cxgbi_ppm *ppm, u32 tag)
0198 {
0199 return !(tag & ppm->tformat.no_ddp_mask);
0200 }
0201
0202 static inline int cxgbi_ppm_sw_tag_is_usable(struct cxgbi_ppm *ppm,
0203 u32 tag)
0204 {
0205
0206 return !(tag & 0x80000000U);
0207 }
0208
0209 static inline int cxgbi_ppm_make_non_ddp_tag(struct cxgbi_ppm *ppm,
0210 u32 sw_tag,
0211 u32 *final_tag)
0212 {
0213 struct cxgbi_tag_format *tformat = &ppm->tformat;
0214
0215 if (!cxgbi_ppm_sw_tag_is_usable(ppm, sw_tag)) {
0216 pr_info("sw_tag 0x%x NOT usable.\n", sw_tag);
0217 return -EINVAL;
0218 }
0219
0220 if (!sw_tag) {
0221 *final_tag = tformat->no_ddp_mask;
0222 } else {
0223 unsigned int shift = tformat->idx_bits + tformat->color_bits;
0224 u32 lower = sw_tag & tformat->idx_clr_mask;
0225 u32 upper = (sw_tag >> shift) << (shift + 1);
0226
0227 *final_tag = upper | tformat->no_ddp_mask | lower;
0228 }
0229 return 0;
0230 }
0231
0232 static inline u32 cxgbi_ppm_decode_non_ddp_tag(struct cxgbi_ppm *ppm,
0233 u32 tag)
0234 {
0235 struct cxgbi_tag_format *tformat = &ppm->tformat;
0236 unsigned int shift = tformat->idx_bits + tformat->color_bits;
0237 u32 lower = tag & tformat->idx_clr_mask;
0238 u32 upper = (tag >> tformat->rsvd_bits) << shift;
0239
0240 return upper | lower;
0241 }
0242
0243 static inline u32 cxgbi_ppm_ddp_tag_get_idx(struct cxgbi_ppm *ppm,
0244 u32 ddp_tag)
0245 {
0246 u32 hw_idx = (ddp_tag >> PPOD_IDX_SHIFT) &
0247 ppm->tformat.idx_mask;
0248
0249 return hw_idx - ppm->base_idx;
0250 }
0251
0252 static inline u32 cxgbi_ppm_make_ddp_tag(unsigned int hw_idx,
0253 unsigned char color)
0254 {
0255 return (hw_idx << PPOD_IDX_SHIFT) | ((u32)color);
0256 }
0257
0258 static inline unsigned long
0259 cxgbi_ppm_get_tag_caller_data(struct cxgbi_ppm *ppm,
0260 u32 ddp_tag)
0261 {
0262 u32 idx = cxgbi_ppm_ddp_tag_get_idx(ppm, ddp_tag);
0263
0264 return ppm->ppod_data[idx].caller_data;
0265 }
0266
0267
0268 static inline int cxgbi_ppm_ddp_tag_update_sw_bits(struct cxgbi_ppm *ppm,
0269 u32 val, u32 orig_tag,
0270 u32 *final_tag)
0271 {
0272 struct cxgbi_tag_format *tformat = &ppm->tformat;
0273 u32 v = val >> tformat->free_bits;
0274
0275 if (v) {
0276 pr_info("sw_bits 0x%x too large, avail bits %u.\n",
0277 val, tformat->free_bits);
0278 return -EINVAL;
0279 }
0280 if (!cxgbi_ppm_is_ddp_tag(ppm, orig_tag))
0281 return -EINVAL;
0282
0283 *final_tag = (val << tformat->rsvd_bits) |
0284 (orig_tag & ppm->tformat.rsvd_mask);
0285 return 0;
0286 }
0287
0288 static inline void cxgbi_ppm_ppod_clear(struct cxgbi_pagepod *ppod)
0289 {
0290 ppod->hdr.vld_tid = 0U;
0291 }
0292
0293 static inline void cxgbi_tagmask_check(unsigned int tagmask,
0294 struct cxgbi_tag_format *tformat)
0295 {
0296 unsigned int bits = fls(tagmask);
0297
0298
0299 tformat->free_bits = 32 - 2 - bits;
0300 tformat->rsvd_bits = bits;
0301 tformat->color_bits = PPOD_IDX_SHIFT;
0302 tformat->idx_bits = bits - 1 - PPOD_IDX_SHIFT;
0303 tformat->no_ddp_mask = 1 << (bits - 1);
0304 tformat->idx_mask = (1 << tformat->idx_bits) - 1;
0305 tformat->color_mask = (1 << PPOD_IDX_SHIFT) - 1;
0306 tformat->idx_clr_mask = (1 << (bits - 1)) - 1;
0307 tformat->rsvd_mask = (1 << bits) - 1;
0308
0309 pr_info("ippm: tagmask 0x%x, rsvd %u=%u+%u+1, mask 0x%x,0x%x, "
0310 "pg %u,%u,%u,%u.\n",
0311 tagmask, tformat->rsvd_bits, tformat->idx_bits,
0312 tformat->color_bits, tformat->no_ddp_mask, tformat->rsvd_mask,
0313 tformat->pgsz_order[0], tformat->pgsz_order[1],
0314 tformat->pgsz_order[2], tformat->pgsz_order[3]);
0315 }
0316
0317 int cxgbi_ppm_find_page_index(struct cxgbi_ppm *ppm, unsigned long pgsz);
0318 void cxgbi_ppm_make_ppod_hdr(struct cxgbi_ppm *ppm, u32 tag,
0319 unsigned int tid, unsigned int offset,
0320 unsigned int length,
0321 struct cxgbi_pagepod_hdr *hdr);
0322 void cxgbi_ppm_ppod_release(struct cxgbi_ppm *, u32 idx);
0323 int cxgbi_ppm_ppods_reserve(struct cxgbi_ppm *, unsigned short nr_pages,
0324 u32 per_tag_pg_idx, u32 *ppod_idx, u32 *ddp_tag,
0325 unsigned long caller_data);
0326 int cxgbi_ppm_init(void **ppm_pp, struct net_device *, struct pci_dev *,
0327 void *lldev, struct cxgbi_tag_format *,
0328 unsigned int iscsi_size, unsigned int llimit,
0329 unsigned int start, unsigned int reserve_factor,
0330 unsigned int edram_start, unsigned int edram_size);
0331 int cxgbi_ppm_release(struct cxgbi_ppm *ppm);
0332 void cxgbi_tagmask_check(unsigned int tagmask, struct cxgbi_tag_format *);
0333 unsigned int cxgbi_tagmask_set(unsigned int ppmax);
0334
0335 #endif