~n-muench/ubuntu/precise/open-vm-tools/open-vm-tools-precise.sid-merge1

« back to all changes in this revision

Viewing changes to modules/linux/vmxnet3/vmxnet3_shm.h

  • Committer: Evan Broder
  • Date: 2010-03-21 23:26:53 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: broder@mit.edu-20100321232653-5a57r7v7ch4o6byv
Merging shared upstream rev into target branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*********************************************************
2
 
 * Copyright (C) 2009 VMware, Inc. All rights reserved.
3
 
 *
4
 
 * This program is free software; you can redistribute it and/or modify it
5
 
 * under the terms of the GNU General Public License as published by the
6
 
 * Free Software Foundation version 2 and no later version.
7
 
 *
8
 
 * This program is distributed in the hope that it will be useful, but
9
 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
 
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11
 
 * for more details.
12
 
 *
13
 
 * You should have received a copy of the GNU General Public License along
14
 
 * with this program; if not, write to the Free Software Foundation, Inc.,
15
 
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
16
 
 *
17
 
 *********************************************************/
18
 
 
19
 
/*
20
 
 * vmxnet3_shm.h --
21
 
 *
22
 
 *      Definitions for shared memory infrastructure for VMXNET3 linux driver.
23
 
 */
24
 
 
25
 
#ifndef _VMXNET3_SHM_H_
26
 
#define _VMXNET3_SHM_H_
27
 
 
28
 
#include "vmxnet3_shm_shared.h"
29
 
#include <linux/miscdevice.h>
30
 
 
31
 
/*
32
 
 * Bumping up the max tx descriptor per packet.
33
 
 * We need one more than VMXNET3_SHM_MAX_FRAGS because of partial header copy.
34
 
 */
35
 
#define VMXNET3_MAX_TXD_PER_PKT_SHM (VMXNET3_SHM_MAX_FRAGS + 1)
36
 
 
37
 
struct vmxnet3_shm_mapped_page
38
 
{
39
 
        struct page *page;
40
 
        void *virt;
41
 
};
42
 
 
43
 
struct vmxnet3_shm_pool
44
 
{
45
 
        struct list_head list;
46
 
        char name[IFNAMSIZ + 16];
47
 
        struct kobject kobj;
48
 
 
49
 
        struct
50
 
        {
51
 
                /* pages backing the map in virtual address order */
52
 
                struct vmxnet3_shm_mapped_page *pages;
53
 
                unsigned int num_pages;
54
 
        } data;
55
 
 
56
 
        struct
57
 
        {
58
 
                /* pages backing the map in virtual address order */
59
 
                struct page *pages[SHM_CTL_SIZE];
60
 
                struct vmxnet3_shm_ctl *ptr;
61
 
        } ctl;
62
 
 
63
 
        struct
64
 
        {
65
 
                /*
66
 
                 * This is a stack of free pages. count is the number of free pages, so
67
 
                 * count - 1 is the topmost free page.
68
 
                 */
69
 
                u16 count;
70
 
                u16 *stack;
71
 
        } allocator;
72
 
 
73
 
        struct
74
 
        {
75
 
                struct vmxnet3_shm_ringentry res[VMXNET3_SHM_MAX_FRAGS];
76
 
                int frags;
77
 
        } partial_tx;
78
 
 
79
 
        struct miscdevice misc_dev;
80
 
 
81
 
        wait_queue_head_t rxq;
82
 
        spinlock_t alloc_lock, tx_lock, rx_lock;
83
 
        struct vmxnet3_adapter *adapter;
84
 
};
85
 
 
86
 
/* Convert ring index to the struct page* or virt address. */
87
 
#define VMXNET3_SHM_IDX2PAGE(shm, idx) (shm->data.pages[(idx)].page)
88
 
#define VMXNET3_SHM_SET_IDX2PAGE(shm, idx, x) (shm->data.pages[(idx)].page = (x))
89
 
 
90
 
#define VMXNET3_SHM_SKB_GETIDX(skb) (compat_skb_transport_offset(skb))
91
 
#define VMXNET3_SHM_SKB_SETIDX(skb, idx) (compat_skb_set_transport_header(skb, idx))
92
 
#define VMXNET3_SHM_SKB_SETLEN(skb, len) (compat_skb_set_network_header(skb, len))
93
 
#define VMXNET3_SHM_SKB_GETLEN(skb) (compat_skb_network_offset(skb))
94
 
 
95
 
int
96
 
vmxnet3_shm_close(struct vmxnet3_adapter *adapter);
97
 
int
98
 
vmxnet3_shm_open(struct vmxnet3_adapter *adapter, char *name, int pool_size);
99
 
int
100
 
vmxnet3_shm_user_rx(struct vmxnet3_shm_pool *shm,
101
 
                u16 idx, u16 len,
102
 
                int trash, int eop);
103
 
void
104
 
vmxnet3_free_skbpages(struct vmxnet3_adapter *adapter, struct sk_buff *skb);
105
 
 
106
 
u16
107
 
vmxnet3_shm_alloc_page(struct vmxnet3_shm_pool *shm);
108
 
void
109
 
vmxnet3_shm_free_page(struct vmxnet3_shm_pool *shm, u16 idx);
110
 
 
111
 
int
112
 
vmxnet3_shm_start_tx(struct sk_buff *skb, struct net_device *dev);
113
 
int
114
 
vmxnet3_shm_rx_skb(struct vmxnet3_adapter *adapter, struct sk_buff *skb);
115
 
 
116
 
/*
117
 
 *-----------------------------------------------------------------------------
118
 
 *
119
 
 * vmxnet3_dev_kfree_skb_* --
120
 
 *
121
 
 *      Covers for dev_kfree_skb*. Deal with the shared memory version of skbs.
122
 
 *
123
 
 * Results:
124
 
 *      None.
125
 
 *
126
 
 * Side effects:
127
 
 *      None.
128
 
 *
129
 
 *-----------------------------------------------------------------------------
130
 
 */
131
 
static inline void
132
 
vmxnet3_dev_kfree_skb(struct vmxnet3_adapter *adapter, struct sk_buff *skb)
133
 
{
134
 
        if (adapter->is_shm)
135
 
                vmxnet3_free_skbpages(adapter, skb);
136
 
 
137
 
        compat_dev_kfree_skb(skb, FREE_WRITE);
138
 
}
139
 
 
140
 
static inline void
141
 
vmxnet3_dev_kfree_skb_any(struct vmxnet3_adapter *adapter, struct sk_buff *skb)
142
 
{
143
 
        if (adapter->is_shm)
144
 
                vmxnet3_free_skbpages(adapter, skb);
145
 
 
146
 
        compat_dev_kfree_skb_any(skb, FREE_WRITE);
147
 
}
148
 
 
149
 
static inline void
150
 
vmxnet3_dev_kfree_skb_irq(struct vmxnet3_adapter *adapter, struct sk_buff *skb)
151
 
{
152
 
        if (adapter->is_shm)
153
 
                vmxnet3_free_skbpages(adapter, skb);
154
 
 
155
 
        compat_dev_kfree_skb_irq(skb, FREE_WRITE);
156
 
}
157
 
 
158
 
/*
159
 
 *-----------------------------------------------------------------------------
160
 
 *
161
 
 * vmxnet3_skb_* --
162
 
 *
163
 
 *      Covers for (compat_)skb_*. Deal with the shared memory version of skbs.
164
 
 *
165
 
 * Results:
166
 
 *      Depends.
167
 
 *
168
 
 * Side effects:
169
 
 *      None.
170
 
 *
171
 
 *-----------------------------------------------------------------------------
172
 
 */
173
 
static inline unsigned int
174
 
vmxnet3_skb_headlen(struct vmxnet3_adapter *adapter, struct sk_buff *skb)
175
 
{
176
 
        if (adapter->is_shm)
177
 
                return VMXNET3_SHM_SKB_GETLEN(skb);
178
 
        else
179
 
                return compat_skb_headlen(skb);
180
 
 
181
 
}
182
 
 
183
 
static inline void
184
 
vmxnet3_skb_put(struct vmxnet3_adapter *adapter, struct sk_buff *skb, unsigned int len)
185
 
{
186
 
        if (!adapter->is_shm) {
187
 
                skb_put(skb, len);
188
 
        } else {
189
 
                unsigned int oldlen = VMXNET3_SHM_SKB_GETLEN(skb);
190
 
                VMXNET3_SHM_SKB_SETLEN(skb, len + oldlen);
191
 
        }
192
 
}
193
 
 
194
 
static inline struct sk_buff*
195
 
vmxnet3_dev_alloc_skb(struct vmxnet3_adapter *adapter, unsigned long length)
196
 
{
197
 
        if (adapter->is_shm) {
198
 
                int idx;
199
 
                struct sk_buff* skb;
200
 
                idx = vmxnet3_shm_alloc_page(adapter->shm);
201
 
                if (idx == SHM_INVALID_IDX)
202
 
                        return NULL;
203
 
 
204
 
 
205
 
                /* The length is arbitrary because that memory shouldn't be used */
206
 
                skb = dev_alloc_skb(100);
207
 
                if (skb == NULL) {
208
 
                        vmxnet3_shm_free_page(adapter->shm, idx);
209
 
                        return NULL;
210
 
                }
211
 
 
212
 
                VMXNET3_SHM_SKB_SETIDX(skb, idx);
213
 
                VMXNET3_SHM_SKB_SETLEN(skb, 0);
214
 
 
215
 
                return skb;
216
 
        } else {
217
 
                return dev_alloc_skb(length);
218
 
        }
219
 
}
220
 
 
221
 
/*
222
 
 *-----------------------------------------------------------------------------
223
 
 *
224
 
 * vmxnet3_map_* --
225
 
 *
226
 
 *      Covers for pci_map_*. Deal with the shared memory version of skbs.
227
 
 *
228
 
 * Results:
229
 
 *      DMA address
230
 
 *
231
 
 * Side effects:
232
 
 *      None.
233
 
 *
234
 
 *-----------------------------------------------------------------------------
235
 
 */
236
 
static inline dma_addr_t
237
 
vmxnet3_map_single(struct vmxnet3_adapter *adapter,
238
 
                struct sk_buff * skb,
239
 
                size_t offset,
240
 
                size_t len,
241
 
                int direction)
242
 
{
243
 
        if (adapter->is_shm) {
244
 
                unsigned long shm_idx = VMXNET3_SHM_SKB_GETIDX(skb);
245
 
                struct page *real_page = VMXNET3_SHM_IDX2PAGE(adapter->shm, shm_idx);
246
 
                return pci_map_page(adapter->pdev,
247
 
                                real_page,
248
 
                                offset,
249
 
                                len,
250
 
                                direction);
251
 
        } else {
252
 
                return pci_map_single(adapter->pdev,
253
 
                                skb->data + offset,
254
 
                                len,
255
 
                                direction);
256
 
        }
257
 
 
258
 
}
259
 
 
260
 
static inline dma_addr_t
261
 
vmxnet3_map_page(struct vmxnet3_adapter *adapter,
262
 
                struct page *page,
263
 
                size_t offset,
264
 
                size_t len,
265
 
                int direction)
266
 
{
267
 
        if (adapter->is_shm) {
268
 
                unsigned long shm_idx = (unsigned long)page;
269
 
                page = VMXNET3_SHM_IDX2PAGE(adapter->shm, shm_idx);
270
 
        }
271
 
 
272
 
        return pci_map_page(adapter->pdev,
273
 
                        page,
274
 
                        offset,
275
 
                        len,
276
 
                        direction);
277
 
}
278
 
 
279
 
/*
280
 
 *-----------------------------------------------------------------------------
281
 
 *
282
 
 * vmxnet3_(put|alloc)_page --
283
 
 *
284
 
 *      Allocation and release of pages. Either use regular or shared memory
285
 
 *      pages.
286
 
 *
287
 
 * Results:
288
 
 *      Depends
289
 
 *
290
 
 * Side effects:
291
 
 *      None.
292
 
 *
293
 
 *-----------------------------------------------------------------------------
294
 
 */
295
 
static inline void
296
 
vmxnet3_put_page(struct vmxnet3_adapter *adapter,
297
 
                struct page *page)
298
 
{
299
 
        if (!adapter->is_shm)
300
 
                put_page(page);
301
 
        else
302
 
                vmxnet3_shm_free_page(adapter->shm, (unsigned long)page);
303
 
}
304
 
 
305
 
static inline void *
306
 
vmxnet3_alloc_page(struct vmxnet3_adapter *adapter)
307
 
{
308
 
        if (adapter->is_shm)
309
 
                return (void*) (unsigned long) vmxnet3_shm_alloc_page(adapter->shm);
310
 
        else
311
 
                return alloc_page(GFP_ATOMIC);
312
 
 
313
 
}
314
 
 
315
 
 
316
 
#endif