]>
git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/drivers/net/cxgbe/clip_tbl.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Chelsio Communications.
10 * Allocate clip entry in HW with associated IPV4/IPv6 address
12 static int clip6_get_mbox(const struct rte_eth_dev
*dev
, const u32
*lip
)
14 struct adapter
*adap
= ethdev2adap(dev
);
16 u64 hi
= ((u64
)lip
[1]) << 32 | lip
[0];
17 u64 lo
= ((u64
)lip
[3]) << 32 | lip
[2];
19 memset(&c
, 0, sizeof(c
));
20 c
.op_to_write
= cpu_to_be32(V_FW_CMD_OP(FW_CLIP_CMD
) |
21 F_FW_CMD_REQUEST
| F_FW_CMD_WRITE
);
22 c
.alloc_to_len16
= cpu_to_be32(F_FW_CLIP_CMD_ALLOC
| FW_LEN16(c
));
25 return t4_wr_mbox_meat(adap
, adap
->mbox
, &c
, sizeof(c
), &c
, false);
29 * Delete clip entry in HW having the associated IPV4/IPV6 address
31 static int clip6_release_mbox(const struct rte_eth_dev
*dev
, const u32
*lip
)
33 struct adapter
*adap
= ethdev2adap(dev
);
35 u64 hi
= ((u64
)lip
[1]) << 32 | lip
[0];
36 u64 lo
= ((u64
)lip
[3]) << 32 | lip
[2];
38 memset(&c
, 0, sizeof(c
));
39 c
.op_to_write
= cpu_to_be32(V_FW_CMD_OP(FW_CLIP_CMD
) |
40 F_FW_CMD_REQUEST
| F_FW_CMD_READ
);
41 c
.alloc_to_len16
= cpu_to_be32(F_FW_CLIP_CMD_FREE
| FW_LEN16(c
));
44 return t4_wr_mbox_meat(adap
, adap
->mbox
, &c
, sizeof(c
), &c
, false);
48 * cxgbe_clip_release - Release associated CLIP entry
49 * @ce: clip entry to release
51 * Releases ref count and frees up a clip entry from CLIP table
53 void cxgbe_clip_release(struct rte_eth_dev
*dev
, struct clip_entry
*ce
)
57 t4_os_lock(&ce
->lock
);
58 if (rte_atomic32_dec_and_test(&ce
->refcnt
)) {
59 ret
= clip6_release_mbox(dev
, ce
->addr
);
61 dev_debug(adap
, "CLIP FW DEL CMD failed: %d", ret
);
63 t4_os_unlock(&ce
->lock
);
67 * find_or_alloc_clipe - Find/Allocate a free CLIP entry
69 * @lip: IPV4/IPV6 address to compare/add
70 * Returns pointer to the IPV4/IPV6 entry found/created
72 * Finds/Allocates an CLIP entry to be used for a filter rule.
74 static struct clip_entry
*find_or_alloc_clipe(struct clip_tbl
*c
,
77 struct clip_entry
*end
, *e
;
78 struct clip_entry
*first_free
= NULL
;
79 unsigned int clipt_size
= c
->clipt_size
;
81 for (e
= &c
->cl_list
[0], end
= &c
->cl_list
[clipt_size
]; e
!= end
; ++e
) {
82 if (rte_atomic32_read(&e
->refcnt
) == 0) {
86 if (memcmp(lip
, e
->addr
, sizeof(e
->addr
)) == 0)
102 static struct clip_entry
*t4_clip_alloc(struct rte_eth_dev
*dev
,
105 struct adapter
*adap
= ethdev2adap(dev
);
106 struct clip_tbl
*ctbl
= adap
->clipt
;
107 struct clip_entry
*ce
;
113 t4_os_write_lock(&ctbl
->lock
);
114 ce
= find_or_alloc_clipe(ctbl
, lip
);
116 t4_os_lock(&ce
->lock
);
117 if (!rte_atomic32_read(&ce
->refcnt
)) {
118 rte_memcpy(ce
->addr
, lip
, sizeof(ce
->addr
));
120 ce
->type
= FILTER_TYPE_IPV6
;
121 rte_atomic32_set(&ce
->refcnt
, 1);
122 ret
= clip6_get_mbox(dev
, lip
);
125 "CLIP FW ADD CMD failed: %d",
128 ce
->type
= FILTER_TYPE_IPV4
;
131 rte_atomic32_inc(&ce
->refcnt
);
133 t4_os_unlock(&ce
->lock
);
135 t4_os_write_unlock(&ctbl
->lock
);
137 return ret
? NULL
: ce
;
141 * cxgbe_clip_alloc - Allocate a IPV6 CLIP entry
142 * @dev: rte_eth_dev pointer
143 * @lip: IPV6 address to add
144 * Returns pointer to the CLIP entry created
146 * Allocates a IPV6 CLIP entry to be used for a filter rule.
148 struct clip_entry
*cxgbe_clip_alloc(struct rte_eth_dev
*dev
, u32
*lip
)
150 return t4_clip_alloc(dev
, lip
, FILTER_TYPE_IPV6
);
154 * Initialize CLIP Table
156 struct clip_tbl
*t4_init_clip_tbl(unsigned int clipt_start
,
157 unsigned int clipt_end
)
159 unsigned int clipt_size
;
160 struct clip_tbl
*ctbl
;
163 if (clipt_start
>= clipt_end
)
166 clipt_size
= clipt_end
- clipt_start
+ 1;
168 ctbl
= t4_os_alloc(sizeof(*ctbl
) +
169 clipt_size
* sizeof(struct clip_entry
));
173 ctbl
->clipt_start
= clipt_start
;
174 ctbl
->clipt_size
= clipt_size
;
176 t4_os_rwlock_init(&ctbl
->lock
);
178 for (i
= 0; i
< ctbl
->clipt_size
; i
++) {
179 t4_os_lock_init(&ctbl
->cl_list
[i
].lock
);
180 rte_atomic32_set(&ctbl
->cl_list
[i
].refcnt
, 0);
189 void t4_cleanup_clip_tbl(struct adapter
*adap
)
192 t4_os_free(adap
->clipt
);