summaryrefslogtreecommitdiff
path: root/lib/internal.h
blob: b85619aa514c7030c5234cfe38f466e5c9742613 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
 * Linux WiMax
 * Internal API and declarations
 *
 *
 * Copyright (C) 2007-2008 Intel Corporation. All rights reserved.
 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * 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.
 *   * Neither the name of Intel Corporation nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "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 THE COPYRIGHT
 * OWNER 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.
 *
 *
 */
#ifndef __lib_internal_h__
#define __lib_internal_h__

enum {
#define __WIMAXLL_IFNAME_LEN 32
	/**
	 * WIMAXLL_IFNAME_LEN - Maximum size of a wimax interface
	 *     name.
	 */
	WIMAXLL_IFNAME_LEN = __WIMAXLL_IFNAME_LEN,
	/**
	 * WMAX_MC_MAX - Maximum number of multicast groups that a
	 *     WiMAX interface can offer (this doesn't count the
	 *     reports group, which is separate).
	 */
	WIMAXLL_MC_MAX = 5,
};


struct wimaxll_mc_handle;


/**
 * A description of a generic netlink multicast group
 *
 * \param name Name of the group
 * \param id ID of the group
 */
struct wimaxll_mc_group {
	char name[GENL_NAMSIZ];
	int id;
	struct wimaxll_mc_handle *mch;
};


/**
 * A WiMax control pipe handle
 *
 * This type is opaque to the user
 *
 * \internal
 *
 * In order to simplify multithread support, we use to different \a
 * libnl handles, one for sending to the kernel, one (for each pipe
 * open to a multicast group) for reading from the kernel. This allows
 * us to parallelize \c wimaxll_msg_write() and \c wimaxll_msg_read() at
 * the same time in a multithreaded environment.
 *
 * FIXME: this needs some rewriting
 *
 * \param ifidx Interface Index 
 * \param nlh_tx handle for writing to the kernel.
 *     Internal note: You \b have \b to set the handlers for
 *     %NL_CB_VALID and nl_cb_err() callbacks, as each callsite will
 *     do it to suit their needs. See wimaxll_rfkill() for an
 *     example. Any other callback you are supposed to restore to what
 *     it was before.
 * \param gnl_family_id Generic Netlink Family ID assigned to the device
 * \param mc_msg Index in the \a gnl_mc array of the "msg"
 *     multicast group.
 * \param name name of the wimax interface
 * \param gnl_mc Array of information about the different multicast
 *     groups supported by the device. At least the "msg" group is
 *     always supported. The rest are optional and depend on what the
 *     driver implements.
 */
struct wimaxll_handle {
	unsigned ifidx;
	struct nl_handle *nlh_tx;
	int gnl_family_id;
	unsigned mc_msg;
	char name[__WIMAXLL_IFNAME_LEN];
	struct wimaxll_mc_group gnl_mc[WIMAXLL_MC_MAX];
};


/**
 * Multicast group handle
 *
 * \internal
 *
 * This structure encapsulates all that we need to read from a single
 * multicast group. We could have a single handle for doing all, but
 * by definition of the interface, different multicast groups carry
 * different traffic (with different needs). Rather than multiplex it
 * here, we multiplex at the kernel by sending it via an specific pipe
 * that knows how to handle it already.
 *
 * This way the driver can define it's own private pipes (if needed)
 * for high bandwidth traffic (for example, tracing information)
 * without affecting the rest of the groups (channels).
 */
struct wimaxll_mc_handle {
	int idx;
	struct wimaxll_handle *wmx;
	struct nl_handle *nlh_rx;
	struct nl_cb *nl_cb;
	ssize_t result;

	wimaxll_msg_to_user_cb_f msg_to_user_cb;
	struct wimaxll_gnl_cb_context *msg_to_user_context;

	wimaxll_state_change_cb_f state_change_cb;
	struct wimaxll_gnl_cb_context *state_change_context;
};


static inline
void wimaxll_mch_maybe_set_result(struct wimaxll_mc_handle *mch, int val)
{
	if (mch->result == -EINPROGRESS)
		mch->result = val;
}


/* Utilities */
ssize_t wimaxll_wait_for_rp_result(struct wimaxll_handle *);
int wimaxll_wait_for_ack(struct wimaxll_handle *);
int wimaxll_gnl_handle_msg_to_user(struct wimaxll_handle *,
				 struct wimaxll_mc_handle *,
				 struct nl_msg *);
int wimaxll_gnl_handle_state_change(struct wimaxll_handle *,
				  struct wimaxll_mc_handle *,
				  struct nl_msg *);
int wimaxll_gnl_error_cb(struct sockaddr_nl *, struct nlmsgerr *, void *);
struct wimaxll_mc_handle *__wimaxll_get_mc_handle(struct wimaxll_handle *,
					      int pipe_id);


#define wimaxll_container_of(pointer, type, member)			\
({									\
	type *object = NULL;						\
	size_t offset = (void *) &object->member - (void *) object;	\
	(type *) ((void *) pointer - offset);				\
})


/*
 * wimaxll_family_id - Return the associated Generic Netlink family ID
 *
 * @wmx: WiMax interface for which to provide the ID.
 */
static inline
int wimaxll_family_id(struct wimaxll_handle *wmx)
{
	return wmx->gnl_family_id;
}


void wimaxll_msg(struct wimaxll_handle *, const char *fmt, ...)
	__attribute__ ((format(printf, 2, 3)));

#endif /* #ifndef __lib_internal_h__ */