port_bitmap.h revision aa97dd1c
1/*
2 * Copyright (c) 2016  Intel Corporation.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef _PORT_BITMAP_H_
17#define _PORT_BITMAP_H_
18
19#ifdef __cplusplus
20extern "C" {
21#endif
22
23/*
24 * Simple implementation of bitmap for all possible L4 ports [0-UINT16_MAX].
25 */
26
27#define MAX_PORT_NUM	(UINT16_MAX + 1)
28
29#define PORT_BLK(p)	((p) / (sizeof(uint32_t) * CHAR_BIT))
30#define PORT_IDX(p)	((p) % (sizeof(uint32_t) * CHAR_BIT))
31
32#define	MAX_PORT_BLK	PORT_BLK(MAX_PORT_NUM)
33
34struct tle_pbm {
35	uint32_t nb_set; /* number of bits set. */
36	uint32_t blk;    /* last block with free entry. */
37	uint32_t bm[MAX_PORT_BLK];
38};
39
40static inline void
41tle_pbm_init(struct tle_pbm *pbm, uint32_t blk)
42{
43	pbm->bm[0] = 1;
44	pbm->nb_set = 1;
45	pbm->blk = blk;
46}
47
48static inline void
49tle_pbm_set(struct tle_pbm *pbm, uint16_t port)
50{
51	uint32_t i, b, v;
52
53	i = PORT_BLK(port);
54	b = 1 << PORT_IDX(port);
55	v = pbm->bm[i];
56	pbm->bm[i] = v | b;
57	pbm->nb_set += (v & b) == 0;
58}
59
60static inline void
61tle_pbm_clear(struct tle_pbm *pbm, uint16_t port)
62{
63	uint32_t i, b, v;
64
65	i = PORT_BLK(port);
66	b = 1 << PORT_IDX(port);
67	v = pbm->bm[i];
68	pbm->bm[i] = v & ~b;
69	pbm->nb_set -= (v & b) != 0;
70}
71
72
73static inline uint32_t
74tle_pbm_check(const struct tle_pbm *pbm, uint16_t port)
75{
76	uint32_t i, v;
77
78	i = PORT_BLK(port);
79	v = pbm->bm[i] >> PORT_IDX(port);
80	return v & 1;
81}
82
83static inline uint16_t
84tle_pbm_find_range(struct tle_pbm *pbm, uint32_t start_blk, uint32_t end_blk)
85{
86	uint32_t i, v;
87	uint16_t p;
88
89	if (pbm->nb_set == MAX_PORT_NUM)
90		return 0;
91
92	p = 0;
93	for (i = start_blk; i != end_blk; i++) {
94		i %= RTE_DIM(pbm->bm);
95		v = pbm->bm[i];
96		if (v != UINT32_MAX) {
97			for (p = i * (sizeof(pbm->bm[0]) * CHAR_BIT);
98					(v & 1) != 0; v >>= 1, p++)
99				;
100
101			pbm->blk = i;
102			break;
103		}
104	}
105	return p;
106}
107
108#ifdef __cplusplus
109}
110#endif
111
112#endif /* _PORT_BITMAP_H_ */
113