~ubuntu-branches/ubuntu/trusty/virtualbox-lts-xenial/trusty-proposed

« back to all changes in this revision

Viewing changes to src/VBox/Devices/PC/ipxe/src/drivers/net/vxge/vxge_main.c

  • Committer: Package Import Robot
  • Author(s): Gianfranco Costamagna
  • Date: 2016-02-23 14:28:26 UTC
  • Revision ID: package-import@ubuntu.com-20160223142826-bdu69el2z6wa2a44
Tags: upstream-4.3.36-dfsg
ImportĀ upstreamĀ versionĀ 4.3.36-dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * vxge-main.c: iPXE driver for Neterion Inc's X3100 Series 10GbE
 
3
 *              PCIe I/O Virtualized Server Adapter.
 
4
 *
 
5
 * Copyright(c) 2002-2010 Neterion Inc.
 
6
 *
 
7
 * This software may be used and distributed according to the terms of
 
8
 * the GNU General Public License (GPL), incorporated herein by
 
9
 * reference.  Drivers based on or derived from this code fall under
 
10
 * the GPL and must retain the authorship, copyright and license
 
11
 * notice.
 
12
 *
 
13
 */
 
14
 
 
15
FILE_LICENCE(GPL2_ONLY);
 
16
 
 
17
#include <stdlib.h>
 
18
#include <stdio.h>
 
19
#include <string.h>
 
20
#include <ipxe/io.h>
 
21
#include <errno.h>
 
22
#include <byteswap.h>
 
23
#include <ipxe/pci.h>
 
24
#include <ipxe/malloc.h>
 
25
#include <ipxe/if_ether.h>
 
26
#include <ipxe/ethernet.h>
 
27
#include <ipxe/iobuf.h>
 
28
#include <ipxe/netdevice.h>
 
29
#include <ipxe/timer.h>
 
30
#include <nic.h>
 
31
 
 
32
#include "vxge_main.h"
 
33
#include "vxge_reg.h"
 
34
 
 
35
/* function modes strings */
 
36
static char *vxge_func_mode_names[] = {
 
37
        "Single Function - 1 func, 17 vpath",
 
38
        "Multi Function 8 - 8 func, 2 vpath per func",
 
39
        "SRIOV 17 - 17 VF, 1 vpath per VF",
 
40
        "WLPEX/SharedIO 17 - 17 VH, 1 vpath/func/hierarchy",
 
41
        "WLPEX/SharedIO 8 - 8 VH, 2 vpath/func/hierarchy",
 
42
        "Multi Function 17 - 17 func, 1 vpath per func",
 
43
        "SRIOV 8 - 1 PF, 7 VF, 2 vpath per VF",
 
44
        "SRIOV 4 - 1 PF, 3 VF, 4 vpath per VF",
 
45
        "Multi Function 2 - 2 func, 8 vpath per func",
 
46
        "Multi Function 4 - 4 func, 4 vpath per func",
 
47
        "WLPEX/SharedIO 4 - 17 func, 1 vpath per func (PCIe ARI)",
 
48
        "Multi Function 8 - For ESX DirectIO - 8 func, 2 vpath per func",
 
49
};
 
50
 
 
51
static inline int is_vxge_card_up(struct vxgedev *vdev)
 
52
{
 
53
        return test_bit(__VXGE_STATE_CARD_UP, vdev->state);
 
54
}
 
55
 
 
56
/*
 
57
 * vxge_xmit_compl
 
58
 *
 
59
 * If an interrupt was raised to indicate DMA complete of the Tx packet,
 
60
 * this function is called. It identifies the last TxD whose buffer was
 
61
 * freed and frees all skbs whose data have already DMA'ed into the NICs
 
62
 * internal memory.
 
63
 */
 
64
enum vxge_hw_status
 
65
vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw,
 
66
                struct vxge_hw_fifo_txd *txdp, enum vxge_hw_fifo_tcode tcode)
 
67
{
 
68
        struct net_device *netdev;
 
69
        struct io_buffer *tx_iob = NULL;
 
70
 
 
71
        vxge_trace();
 
72
 
 
73
        netdev = fifo_hw->vpathh->hldev->ndev;
 
74
 
 
75
        tx_iob = (struct io_buffer *)(intptr_t)txdp->host_control;
 
76
 
 
77
        if (tcode == VXGE_HW_FIFO_T_CODE_OK) {
 
78
                netdev_tx_complete(netdev, tx_iob);
 
79
        } else {
 
80
                netdev_tx_complete_err(netdev, tx_iob, -EINVAL);
 
81
                vxge_debug(VXGE_ERR, "%s: transmit failed, tcode %d\n",
 
82
                                netdev->name, tcode);
 
83
        }
 
84
 
 
85
        memset(txdp, 0, sizeof(struct vxge_hw_fifo_txd));
 
86
 
 
87
        return VXGE_HW_OK;
 
88
}
 
89
 
 
90
/* reset vpaths */
 
91
enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev)
 
92
{
 
93
        enum vxge_hw_status status = VXGE_HW_OK;
 
94
        struct __vxge_hw_virtualpath *vpath;
 
95
 
 
96
        vxge_trace();
 
97
 
 
98
        vpath = vdev->vpath.vpathh;
 
99
 
 
100
        if (vpath) {
 
101
                if ((status = vxge_hw_vpath_reset(vpath)) == VXGE_HW_OK) {
 
102
                        if (is_vxge_card_up(vdev) &&
 
103
                                (status = vxge_hw_vpath_recover_from_reset(
 
104
                                        vpath)) != VXGE_HW_OK) {
 
105
                                vxge_debug(VXGE_ERR, "vxge_hw_vpath_recover_"
 
106
                                        "from_reset failed\n");
 
107
                                return status;
 
108
                        } else {
 
109
                                status = __vxge_hw_vpath_reset_check(vpath);
 
110
                                if (status != VXGE_HW_OK) {
 
111
                                        vxge_debug(VXGE_ERR,
 
112
                                        "__vxge_hw_vpath_reset_check error\n");
 
113
                                        return status;
 
114
                                }
 
115
                        }
 
116
                } else {
 
117
                        vxge_debug(VXGE_ERR, "vxge_hw_vpath_reset failed\n");
 
118
                        return status;
 
119
                }
 
120
        }
 
121
        return status;
 
122
}
 
123
 
 
124
/* close vpaths */
 
125
void vxge_close_vpaths(struct vxgedev *vdev)
 
126
{
 
127
 
 
128
        if (vdev->vpath.vpathh && vdev->vpath.is_open)
 
129
                vxge_hw_vpath_close(vdev->vpath.vpathh);
 
130
 
 
131
        vdev->vpath.is_open = 0;
 
132
        vdev->vpath.vpathh = NULL;
 
133
}
 
134
 
 
135
/* open vpaths */
 
136
int vxge_open_vpaths(struct vxgedev *vdev)
 
137
{
 
138
        enum vxge_hw_status status;
 
139
        struct __vxge_hw_device *hldev;
 
140
 
 
141
        hldev = (struct __vxge_hw_device  *)pci_get_drvdata(vdev->pdev);
 
142
 
 
143
        vdev->vpath.vpathh = &hldev->virtual_path;
 
144
        vdev->vpath.fifo.ndev = vdev->ndev;
 
145
        vdev->vpath.fifo.pdev = vdev->pdev;
 
146
        vdev->vpath.fifo.fifoh = &hldev->virtual_path.fifoh;
 
147
        vdev->vpath.ring.ndev = vdev->ndev;
 
148
        vdev->vpath.ring.pdev = vdev->pdev;
 
149
        vdev->vpath.ring.ringh = &hldev->virtual_path.ringh;
 
150
 
 
151
        status = vxge_hw_vpath_open(vdev->devh, &vdev->vpath);
 
152
        if (status == VXGE_HW_OK) {
 
153
                vdev->vpath.is_open = 1;
 
154
        } else {
 
155
                vxge_debug(VXGE_ERR,
 
156
                        "%s: vpath: %d failed to open "
 
157
                        "with status: %d\n",
 
158
                        vdev->ndev->name, vdev->vpath.device_id,
 
159
                        status);
 
160
                vxge_close_vpaths(vdev);
 
161
                return status;
 
162
        }
 
163
 
 
164
        hldev->vpaths_deployed |= vxge_mBIT(vdev->vpath.vpathh->vp_id);
 
165
 
 
166
        return VXGE_HW_OK;
 
167
}
 
168
 
 
169
/** Functions that implement the iPXE driver API **/
 
170
 
 
171
/**
 
172
 * vxge_xmit
 
173
 * @skb : the socket buffer containing the Tx data.
 
174
 * @dev : device pointer.
 
175
 *
 
176
 * This function is the Tx entry point of the driver. Neterion NIC supports
 
177
 * certain protocol assist features on Tx side, namely  CSO, S/G, LSO.
 
178
 */
 
179
static int
 
180
vxge_xmit(struct net_device *dev, struct io_buffer *iobuf)
 
181
{
 
182
        struct vxge_fifo *fifo = NULL;
 
183
        struct vxgedev *vdev = NULL;
 
184
        struct __vxge_hw_fifo *fifoh;
 
185
        struct vxge_hw_fifo_txd *txdp;
 
186
 
 
187
        vxge_trace();
 
188
 
 
189
        vdev = (struct vxgedev *)netdev_priv(dev);
 
190
 
 
191
        if (!is_vxge_card_up(vdev)) {
 
192
                vxge_debug(VXGE_ERR,
 
193
                        "%s: vdev not initialized\n", dev->name);
 
194
                return -EIO;
 
195
        }
 
196
 
 
197
        if (!netdev_link_ok(dev)) {
 
198
                vxge_debug(VXGE_ERR,
 
199
                        "%s: Link down, transmit failed\n", dev->name);
 
200
                return -ENETDOWN;
 
201
        }
 
202
 
 
203
        fifo = &vdev->vpath.fifo;
 
204
        fifoh = fifo->fifoh;
 
205
 
 
206
        txdp = vxge_hw_fifo_free_txdl_get(fifoh);
 
207
        if (!txdp) {
 
208
                vxge_debug(VXGE_ERR,
 
209
                        "%s: Out of tx descriptors\n", dev->name);
 
210
                return -ENOBUFS;
 
211
        }
 
212
 
 
213
        vxge_debug(VXGE_XMIT, "%s: %s:%d fifoh offset= %d\n",
 
214
                dev->name, __func__, __LINE__, fifoh->sw_offset);
 
215
 
 
216
        vxge_hw_fifo_txdl_buffer_set(fifoh, txdp, iobuf);
 
217
 
 
218
        vxge_hw_fifo_txdl_post(fifoh, txdp);
 
219
 
 
220
        return 0;
 
221
}
 
222
 
 
223
/*
 
224
 *  vxge_poll
 
225
 *  @ndev: net device pointer
 
226
 *
 
227
 *  This function acks the interrupt. It polls for rx packets
 
228
 *  and send to upper layer. It also checks for tx completion
 
229
 *  and frees iobs.
 
230
 */
 
231
static void vxge_poll(struct net_device *ndev)
 
232
{
 
233
        struct __vxge_hw_device  *hldev;
 
234
        struct vxgedev *vdev;
 
235
 
 
236
        vxge_debug(VXGE_POLL, "%s:%d \n", __func__, __LINE__);
 
237
 
 
238
        vdev = (struct vxgedev *)netdev_priv(ndev);
 
239
        hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev);
 
240
 
 
241
        if (!is_vxge_card_up(vdev))
 
242
                return;
 
243
 
 
244
        /* process alarm and acknowledge the interrupts */
 
245
        vxge_hw_device_begin_irq(hldev);
 
246
 
 
247
        vxge_hw_vpath_poll_tx(&hldev->virtual_path.fifoh);
 
248
 
 
249
        vxge_hw_vpath_poll_rx(&hldev->virtual_path.ringh);
 
250
}
 
251
 
 
252
/*
 
253
 * vxge_irq - enable or Disable interrupts
 
254
 *
 
255
 * @netdev   netdevice sturcture reference
 
256
 * @action   requested interrupt action
 
257
 */
 
258
static void vxge_irq(struct net_device *netdev __unused, int action)
 
259
{
 
260
        struct __vxge_hw_device  *hldev;
 
261
        struct vxgedev *vdev;
 
262
 
 
263
        vxge_debug(VXGE_INFO,
 
264
                "%s:%d action(%d)\n", __func__, __LINE__, action);
 
265
 
 
266
        vdev = (struct vxgedev *)netdev_priv(netdev);
 
267
        hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev);
 
268
 
 
269
        switch (action) {
 
270
        case DISABLE:
 
271
                vxge_hw_device_mask_all(hldev);
 
272
                break;
 
273
        default:
 
274
                vxge_hw_device_unmask_all(hldev);
 
275
                break;
 
276
        }
 
277
}
 
278
 
 
279
/**
 
280
 * vxge_open
 
281
 * @dev: pointer to the device structure.
 
282
 *
 
283
 * This function is the open entry point of the driver. It mainly calls a
 
284
 * function to allocate Rx buffers and inserts them into the buffer
 
285
 * descriptors and then enables the Rx part of the NIC.
 
286
 * Return value: '0' on success and an appropriate (-)ve integer as
 
287
 * defined in errno.h file on failure.
 
288
 */
 
289
int
 
290
vxge_open(struct net_device *dev)
 
291
{
 
292
        enum vxge_hw_status status;
 
293
        struct vxgedev *vdev;
 
294
        struct __vxge_hw_device *hldev;
 
295
        int ret = 0;
 
296
 
 
297
        vxge_debug(VXGE_INFO, "%s: %s:%d\n",
 
298
                        VXGE_DRIVER_NAME, __func__, __LINE__);
 
299
 
 
300
        vdev = (struct vxgedev *)netdev_priv(dev);
 
301
        hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev);
 
302
 
 
303
        /* make sure you have link off by default every time Nic is
 
304
         * initialized */
 
305
        netdev_link_down(dev);
 
306
 
 
307
        /* Open VPATHs */
 
308
        status = vxge_open_vpaths(vdev);
 
309
        if (status != VXGE_HW_OK) {
 
310
                vxge_debug(VXGE_ERR, "%s: fatal: Vpath open failed\n",
 
311
                                VXGE_DRIVER_NAME);
 
312
                ret = -EPERM;
 
313
                goto out0;
 
314
        }
 
315
 
 
316
        vdev->mtu = VXGE_HW_DEFAULT_MTU;
 
317
        /* set initial mtu before enabling the device */
 
318
        status = vxge_hw_vpath_mtu_set(vdev->vpath.vpathh, vdev->mtu);
 
319
        if (status != VXGE_HW_OK) {
 
320
                vxge_debug(VXGE_ERR,
 
321
                        "%s: fatal: can not set new MTU\n", dev->name);
 
322
                ret = -EPERM;
 
323
                goto out2;
 
324
        }
 
325
        vxge_debug(VXGE_INFO,
 
326
                "%s: MTU is %d\n", vdev->ndev->name, vdev->mtu);
 
327
 
 
328
        set_bit(__VXGE_STATE_CARD_UP, vdev->state);
 
329
 
 
330
        wmb();
 
331
 
 
332
        if (vxge_hw_device_link_state_get(vdev->devh) == VXGE_HW_LINK_UP) {
 
333
                netdev_link_up(vdev->ndev);
 
334
                vxge_debug(VXGE_INFO, "%s: Link Up\n", vdev->ndev->name);
 
335
        }
 
336
 
 
337
        vxge_hw_device_intr_enable(hldev);
 
338
 
 
339
        vxge_hw_vpath_enable(vdev->vpath.vpathh);
 
340
        wmb();
 
341
        vxge_hw_vpath_rx_doorbell_init(vdev->vpath.vpathh);
 
342
 
 
343
        goto out0;
 
344
 
 
345
out2:
 
346
        vxge_close_vpaths(vdev);
 
347
out0:
 
348
        vxge_debug(VXGE_INFO, "%s: %s:%d  Exiting...\n",
 
349
                                dev->name, __func__, __LINE__);
 
350
        return ret;
 
351
}
 
352
 
 
353
/**
 
354
 * vxge_close
 
355
 * @dev: device pointer.
 
356
 *
 
357
 * This is the stop entry point of the driver. It needs to undo exactly
 
358
 * whatever was done by the open entry point, thus it's usually referred to
 
359
 * as the close function.Among other things this function mainly stops the
 
360
 * Rx side of the NIC and frees all the Rx buffers in the Rx rings.
 
361
 * Return value: '0' on success and an appropriate (-)ve integer as
 
362
 * defined in errno.h file on failure.
 
363
 */
 
364
static void vxge_close(struct net_device *dev)
 
365
{
 
366
        struct vxgedev *vdev;
 
367
        struct __vxge_hw_device *hldev;
 
368
 
 
369
        vxge_debug(VXGE_INFO, "%s: %s:%d\n",
 
370
                dev->name, __func__, __LINE__);
 
371
 
 
372
        vdev = (struct vxgedev *)netdev_priv(dev);
 
373
        hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev);
 
374
 
 
375
        if (!is_vxge_card_up(vdev))
 
376
                return;
 
377
 
 
378
        clear_bit(__VXGE_STATE_CARD_UP, vdev->state);
 
379
 
 
380
        vxge_hw_vpath_set_zero_rx_frm_len(hldev);
 
381
 
 
382
        netdev_link_down(vdev->ndev);
 
383
        vxge_debug(VXGE_INFO, "%s: Link Down\n", vdev->ndev->name);
 
384
 
 
385
        /* Note that at this point xmit() is stopped by upper layer */
 
386
        vxge_hw_device_intr_disable(hldev);
 
387
 
 
388
        /* Multi function shares INTA, hence we should
 
389
         * leave it in enabled state
 
390
         */
 
391
        if (is_mf(hldev->hw_info.function_mode))
 
392
                vxge_hw_device_unmask_all(hldev);
 
393
 
 
394
        vxge_reset_all_vpaths(vdev);
 
395
 
 
396
        vxge_close_vpaths(vdev);
 
397
 
 
398
        vxge_debug(VXGE_INFO,
 
399
                "%s: %s:%d  Exiting...\n", dev->name, __func__, __LINE__);
 
400
}
 
401
 
 
402
static struct net_device_operations vxge_operations;
 
403
 
 
404
int vxge_device_register(struct __vxge_hw_device *hldev,
 
405
                                struct vxgedev **vdev_out)
 
406
{
 
407
        struct net_device *ndev;
 
408
        struct vxgedev *vdev;
 
409
        int ret = 0;
 
410
 
 
411
        *vdev_out = NULL;
 
412
 
 
413
        ndev = alloc_etherdev(sizeof(struct vxgedev));
 
414
        if (ndev == NULL) {
 
415
                vxge_debug(VXGE_ERR, "%s : device allocation failed\n",
 
416
                                __func__);
 
417
                ret = -ENODEV;
 
418
                goto _out0;
 
419
        }
 
420
 
 
421
        vxge_debug(VXGE_INFO, "%s:%d  netdev registering\n",
 
422
                __func__, __LINE__);
 
423
        vdev = netdev_priv(ndev);
 
424
        memset(vdev, 0, sizeof(struct vxgedev));
 
425
 
 
426
        vdev->ndev = ndev;
 
427
        vdev->devh = hldev;
 
428
        vdev->pdev = hldev->pdev;
 
429
 
 
430
        ndev->dev = &vdev->pdev->dev;
 
431
        /* Associate vxge-specific network operations operations with
 
432
         * generic network device layer */
 
433
        netdev_init(ndev, &vxge_operations);
 
434
 
 
435
        memcpy(ndev->hw_addr,
 
436
                (u8 *)hldev->hw_info.mac_addrs[hldev->first_vp_id], ETH_ALEN);
 
437
 
 
438
        if (register_netdev(ndev)) {
 
439
                vxge_debug(VXGE_ERR, "%s : device registration failed!\n",
 
440
                        __func__);
 
441
                ret = -ENODEV;
 
442
                goto _out2;
 
443
        }
 
444
 
 
445
        /* Leave link state as off at this point, when the link change
 
446
         * interrupt comes the state will be automatically changed to
 
447
         * the right state.
 
448
         */
 
449
 
 
450
        vxge_debug(VXGE_INFO, "%s: Ethernet device registered\n",
 
451
                VXGE_DRIVER_NAME);
 
452
 
 
453
        *vdev_out = vdev;
 
454
 
 
455
        return ret;
 
456
_out2:
 
457
        netdev_put(ndev);
 
458
_out0:
 
459
        return ret;
 
460
}
 
461
 
 
462
/*
 
463
 * vxge_device_unregister
 
464
 *
 
465
 * This function will unregister and free network device
 
466
 */
 
467
void
 
468
vxge_device_unregister(struct __vxge_hw_device *hldev)
 
469
{
 
470
        struct net_device *ndev;
 
471
 
 
472
        ndev = hldev->ndev;
 
473
 
 
474
        unregister_netdev(ndev);
 
475
        netdev_nullify(ndev);
 
476
        netdev_put(ndev);
 
477
 
 
478
        vxge_debug(VXGE_INFO, "%s: ethernet device unregistered\n",
 
479
                                VXGE_DRIVER_NAME);
 
480
}
 
481
 
 
482
/**
 
483
 * vxge_probe
 
484
 * @pdev : structure containing the PCI related information of the device.
 
485
 * @id: List of PCI devices supported by the driver listed in vxge_id_table.
 
486
 * Description:
 
487
 * This function is called when a new PCI device gets detected and initializes
 
488
 * it.
 
489
 * Return value:
 
490
 * returns 0 on success and negative on failure.
 
491
 *
 
492
 */
 
493
static int
 
494
vxge_probe(struct pci_device *pdev)
 
495
{
 
496
        struct __vxge_hw_device  *hldev;
 
497
        enum vxge_hw_status status;
 
498
        int ret = 0;
 
499
        u64 vpath_mask = 0;
 
500
        struct vxgedev *vdev;
 
501
        int i;
 
502
        u8 revision, titan1;
 
503
        u32 function_mode;
 
504
        unsigned long mmio_start, mmio_len;
 
505
        void *bar0;
 
506
        struct vxge_hw_device_hw_info hw_info;
 
507
        struct vxge_hw_device_version *fw_version;
 
508
 
 
509
        vxge_debug(VXGE_INFO, "vxge_probe for device " PCI_FMT "\n",
 
510
                        PCI_ARGS(pdev));
 
511
 
 
512
        pci_read_config_byte(pdev, PCI_REVISION_ID, &revision);
 
513
        titan1 = is_titan1(pdev->device, revision);
 
514
 
 
515
        mmio_start = pci_bar_start(pdev, PCI_BASE_ADDRESS_0);
 
516
        mmio_len   = pci_bar_size(pdev, PCI_BASE_ADDRESS_0);
 
517
        vxge_debug(VXGE_INFO, "mmio_start: %#08lx, mmio_len: %#08lx\n",
 
518
                        mmio_start, mmio_len);
 
519
 
 
520
        /* sets the bus master */
 
521
        adjust_pci_device(pdev);
 
522
 
 
523
        bar0 = ioremap(mmio_start, mmio_len);
 
524
        if (!bar0) {
 
525
                vxge_debug(VXGE_ERR,
 
526
                        "%s : cannot remap io memory bar0\n", __func__);
 
527
                ret = -ENODEV;
 
528
                goto _exit0;
 
529
        }
 
530
 
 
531
        status = vxge_hw_device_hw_info_get(pdev, bar0, &hw_info);
 
532
        if (status != VXGE_HW_OK) {
 
533
                vxge_debug(VXGE_ERR,
 
534
                        "%s: Reading of hardware info failed.\n",
 
535
                        VXGE_DRIVER_NAME);
 
536
                ret = -EINVAL;
 
537
                goto _exit1;
 
538
        }
 
539
 
 
540
        if (hw_info.func_id != 0) {
 
541
                /* Non zero function, So do not load the driver */
 
542
                iounmap(bar0);
 
543
                pci_set_drvdata(pdev, NULL);
 
544
                return -EINVAL;
 
545
        }
 
546
 
 
547
 
 
548
        vpath_mask = hw_info.vpath_mask;
 
549
        if (vpath_mask == 0) {
 
550
                vxge_debug(VXGE_ERR,
 
551
                        "%s: No vpaths available in device\n",
 
552
                        VXGE_DRIVER_NAME);
 
553
                ret = -EINVAL;
 
554
                goto _exit1;
 
555
        }
 
556
        vxge_debug(VXGE_INFO,
 
557
                "%s:%d  Vpath mask = %llx\n", __func__, __LINE__,
 
558
                (unsigned long long)vpath_mask);
 
559
 
 
560
        fw_version = &hw_info.fw_version;
 
561
        /* fail the driver loading if firmware is incompatible */
 
562
        if ((fw_version->major != VXGE_CERT_FW_VER_MAJOR) ||
 
563
                (fw_version->minor < VXGE_CERT_FW_VER_MINOR)) {
 
564
                printf("%s: Adapter's current firmware version: %d.%d.%d\n",
 
565
                        VXGE_DRIVER_NAME, fw_version->major,
 
566
                        fw_version->minor, fw_version->build);
 
567
 
 
568
                printf("%s: Upgrade firmware to version %d.%d.%d\n",
 
569
                        VXGE_DRIVER_NAME, VXGE_CERT_FW_VER_MAJOR,
 
570
                        VXGE_CERT_FW_VER_MINOR, VXGE_CERT_FW_VER_BUILD);
 
571
 
 
572
                ret = -EACCES;
 
573
                goto _exit1;
 
574
        }
 
575
 
 
576
        status = vxge_hw_device_initialize(&hldev, bar0, pdev, titan1);
 
577
        if (status != VXGE_HW_OK) {
 
578
                vxge_debug(VXGE_ERR,
 
579
                        "Failed to initialize device (%d)\n", status);
 
580
                        ret = -EINVAL;
 
581
                        goto _exit1;
 
582
        }
 
583
        memcpy(&hldev->hw_info, &hw_info,
 
584
                sizeof(struct vxge_hw_device_hw_info));
 
585
 
 
586
        /* find the vpath id of the first available one */
 
587
        for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++)
 
588
                if (vpath_mask & vxge_mBIT(i)) {
 
589
                        hldev->first_vp_id = i;
 
590
                        break;
 
591
                }
 
592
        /* if FCS stripping is not disabled in MAC fail driver load */
 
593
        if (vxge_hw_vpath_strip_fcs_check(hldev, vpath_mask) != VXGE_HW_OK) {
 
594
                vxge_debug(VXGE_ERR,
 
595
                        "%s: FCS stripping is not disabled in MAC"
 
596
                        " failing driver load\n", VXGE_DRIVER_NAME);
 
597
                ret = -EINVAL;
 
598
                goto _exit2;
 
599
        }
 
600
 
 
601
        /* Read function mode */
 
602
        status = vxge_hw_get_func_mode(hldev, &function_mode);
 
603
        if (status != VXGE_HW_OK)
 
604
                goto _exit2;
 
605
 
 
606
        hldev->hw_info.function_mode = function_mode;
 
607
 
 
608
        /* set private device info */
 
609
        pci_set_drvdata(pdev, hldev);
 
610
 
 
611
        if (vxge_device_register(hldev, &vdev)) {
 
612
                ret = -EINVAL;
 
613
                goto _exit2;
 
614
        }
 
615
 
 
616
        /* set private HW device info */
 
617
        hldev->ndev = vdev->ndev;
 
618
        hldev->vdev = vdev;
 
619
        hldev->pdev = pdev;
 
620
        vdev->mtu = VXGE_HW_DEFAULT_MTU;
 
621
        vdev->bar0 = bar0;
 
622
        vdev->titan1 = titan1;
 
623
        /* Virtual Path count */
 
624
        vdev->vpath.device_id = hldev->first_vp_id;
 
625
        vdev->vpath.vdev = vdev;
 
626
        memcpy((u8 *)vdev->vpath.macaddr,
 
627
                        (u8 *)hldev->hw_info.mac_addrs[hldev->first_vp_id],
 
628
                        ETH_ALEN);
 
629
 
 
630
        hldev->hw_info.serial_number[VXGE_HW_INFO_LEN - 1] = '\0';
 
631
        hldev->hw_info.product_desc[VXGE_HW_INFO_LEN - 1] = '\0';
 
632
        hldev->hw_info.part_number[VXGE_HW_INFO_LEN - 1] = '\0';
 
633
 
 
634
        vxge_debug(VXGE_INFO, "%s: Neterion %s Server Adapter\n",
 
635
                VXGE_DRIVER_NAME, hldev->hw_info.product_desc);
 
636
        vxge_debug(VXGE_INFO, "%s: SERIAL NUMBER: %s\n",
 
637
                VXGE_DRIVER_NAME, hldev->hw_info.serial_number);
 
638
        vxge_debug(VXGE_INFO, "%s: PART NUMBER: %s\n",
 
639
                VXGE_DRIVER_NAME, hldev->hw_info.part_number);
 
640
        vxge_debug(VXGE_INFO, "%s: MAC ADDR: %s\n",
 
641
                VXGE_DRIVER_NAME, eth_ntoa(vdev->vpath.macaddr));
 
642
        vxge_debug(VXGE_INFO,
 
643
                "%s: Firmware version : %s Date : %s\n", VXGE_DRIVER_NAME,
 
644
                hldev->hw_info.fw_version.version,
 
645
                hldev->hw_info.fw_date.date);
 
646
        vxge_debug(VXGE_INFO, "%s: %s Enabled\n",
 
647
                        VXGE_DRIVER_NAME, vxge_func_mode_names[function_mode]);
 
648
 
 
649
        vxge_debug(VXGE_INFO, "%s: %s:%d  Probe Exiting...\n",
 
650
                VXGE_DRIVER_NAME, __func__, __LINE__);
 
651
 
 
652
        return 0;
 
653
 
 
654
_exit2:
 
655
        vxge_hw_device_terminate(hldev);
 
656
_exit1:
 
657
        iounmap(bar0);
 
658
_exit0:
 
659
        pci_set_drvdata(pdev, NULL);
 
660
        printf("%s: WARNING!! Driver loading failed!!\n",
 
661
                VXGE_DRIVER_NAME);
 
662
 
 
663
        return ret;
 
664
}
 
665
 
 
666
/**
 
667
 * vxge_remove - Free the PCI device
 
668
 * @pdev: structure containing the PCI related information of the device.
 
669
 * Description: This function is called by the Pci subsystem to release a
 
670
 * PCI device and free up all resource held up by the device.
 
671
 */
 
672
static void
 
673
vxge_remove(struct pci_device *pdev)
 
674
{
 
675
        struct __vxge_hw_device  *hldev;
 
676
        struct vxgedev *vdev = NULL;
 
677
        struct net_device *ndev;
 
678
 
 
679
        vxge_debug(VXGE_INFO,
 
680
                "%s:%d\n", __func__, __LINE__);
 
681
        hldev = (struct __vxge_hw_device  *) pci_get_drvdata(pdev);
 
682
        if (hldev == NULL)
 
683
                return;
 
684
 
 
685
        ndev = hldev->ndev;
 
686
        vdev = netdev_priv(ndev);
 
687
 
 
688
        iounmap(vdev->bar0);
 
689
 
 
690
        vxge_device_unregister(hldev);
 
691
 
 
692
        vxge_debug(VXGE_INFO,
 
693
                "%s:%d  Device unregistered\n", __func__, __LINE__);
 
694
 
 
695
        vxge_hw_device_terminate(hldev);
 
696
        pci_set_drvdata(pdev, NULL);
 
697
}
 
698
 
 
699
/* vxge net device operations */
 
700
static struct net_device_operations vxge_operations = {
 
701
        .open           = vxge_open,
 
702
        .close          = vxge_close,
 
703
        .transmit       = vxge_xmit,
 
704
        .poll           = vxge_poll,
 
705
        .irq            = vxge_irq,
 
706
};
 
707
 
 
708
static struct pci_device_id vxge_main_nics[] = {
 
709
        /* If you change this, also adjust vxge_nics[] in vxge.c */
 
710
        PCI_ID(0x17d5, 0x5833, "vxge-x3100", "Neterion X3100 Series", 0),
 
711
};
 
712
 
 
713
struct pci_driver vxge_driver __pci_driver = {
 
714
        .ids = vxge_main_nics,
 
715
        .id_count = (sizeof(vxge_main_nics) / sizeof(vxge_main_nics[0])),
 
716
        .probe = vxge_probe,
 
717
        .remove = vxge_remove,
 
718
};