V4L/DVB: v4l2-dev: remove unnecessary lock around atomic clear_bit
[safe/jmp/linux-2.6] / drivers / net / vxge / vxge-config.c
1 /******************************************************************************
2  * This software may be used and distributed according to the terms of
3  * the GNU General Public License (GPL), incorporated herein by reference.
4  * Drivers based on or derived from this code fall under the GPL and must
5  * retain the authorship, copyright and license notice.  This file is not
6  * a complete program and may only be used when the entire operating
7  * system is licensed under the GPL.
8  * See the file COPYING in this distribution for more information.
9  *
10  * vxge-config.c: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
11  *                Virtualized Server Adapter.
12  * Copyright(c) 2002-2009 Neterion Inc.
13  ******************************************************************************/
14 #include <linux/vmalloc.h>
15 #include <linux/etherdevice.h>
16 #include <linux/pci.h>
17 #include <linux/pci_hotplug.h>
18 #include <linux/slab.h>
19
20 #include "vxge-traffic.h"
21 #include "vxge-config.h"
22
23 /*
24  * __vxge_hw_channel_allocate - Allocate memory for channel
25  * This function allocates required memory for the channel and various arrays
26  * in the channel
27  */
28 struct __vxge_hw_channel*
29 __vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph,
30                            enum __vxge_hw_channel_type type,
31         u32 length, u32 per_dtr_space, void *userdata)
32 {
33         struct __vxge_hw_channel *channel;
34         struct __vxge_hw_device *hldev;
35         int size = 0;
36         u32 vp_id;
37
38         hldev = vph->vpath->hldev;
39         vp_id = vph->vpath->vp_id;
40
41         switch (type) {
42         case VXGE_HW_CHANNEL_TYPE_FIFO:
43                 size = sizeof(struct __vxge_hw_fifo);
44                 break;
45         case VXGE_HW_CHANNEL_TYPE_RING:
46                 size = sizeof(struct __vxge_hw_ring);
47                 break;
48         default:
49                 break;
50         }
51
52         channel = kzalloc(size, GFP_KERNEL);
53         if (channel == NULL)
54                 goto exit0;
55         INIT_LIST_HEAD(&channel->item);
56
57         channel->common_reg = hldev->common_reg;
58         channel->first_vp_id = hldev->first_vp_id;
59         channel->type = type;
60         channel->devh = hldev;
61         channel->vph = vph;
62         channel->userdata = userdata;
63         channel->per_dtr_space = per_dtr_space;
64         channel->length = length;
65         channel->vp_id = vp_id;
66
67         channel->work_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
68         if (channel->work_arr == NULL)
69                 goto exit1;
70
71         channel->free_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
72         if (channel->free_arr == NULL)
73                 goto exit1;
74         channel->free_ptr = length;
75
76         channel->reserve_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
77         if (channel->reserve_arr == NULL)
78                 goto exit1;
79         channel->reserve_ptr = length;
80         channel->reserve_top = 0;
81
82         channel->orig_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
83         if (channel->orig_arr == NULL)
84                 goto exit1;
85
86         return channel;
87 exit1:
88         __vxge_hw_channel_free(channel);
89
90 exit0:
91         return NULL;
92 }
93
94 /*
95  * __vxge_hw_channel_free - Free memory allocated for channel
96  * This function deallocates memory from the channel and various arrays
97  * in the channel
98  */
99 void __vxge_hw_channel_free(struct __vxge_hw_channel *channel)
100 {
101         kfree(channel->work_arr);
102         kfree(channel->free_arr);
103         kfree(channel->reserve_arr);
104         kfree(channel->orig_arr);
105         kfree(channel);
106 }
107
108 /*
109  * __vxge_hw_channel_initialize - Initialize a channel
110  * This function initializes a channel by properly setting the
111  * various references
112  */
113 enum vxge_hw_status
114 __vxge_hw_channel_initialize(struct __vxge_hw_channel *channel)
115 {
116         u32 i;
117         struct __vxge_hw_virtualpath *vpath;
118
119         vpath = channel->vph->vpath;
120
121         if ((channel->reserve_arr != NULL) && (channel->orig_arr != NULL)) {
122                 for (i = 0; i < channel->length; i++)
123                         channel->orig_arr[i] = channel->reserve_arr[i];
124         }
125
126         switch (channel->type) {
127         case VXGE_HW_CHANNEL_TYPE_FIFO:
128                 vpath->fifoh = (struct __vxge_hw_fifo *)channel;
129                 channel->stats = &((struct __vxge_hw_fifo *)
130                                 channel)->stats->common_stats;
131                 break;
132         case VXGE_HW_CHANNEL_TYPE_RING:
133                 vpath->ringh = (struct __vxge_hw_ring *)channel;
134                 channel->stats = &((struct __vxge_hw_ring *)
135                                 channel)->stats->common_stats;
136                 break;
137         default:
138                 break;
139         }
140
141         return VXGE_HW_OK;
142 }
143
144 /*
145  * __vxge_hw_channel_reset - Resets a channel
146  * This function resets a channel by properly setting the various references
147  */
148 enum vxge_hw_status
149 __vxge_hw_channel_reset(struct __vxge_hw_channel *channel)
150 {
151         u32 i;
152
153         for (i = 0; i < channel->length; i++) {
154                 if (channel->reserve_arr != NULL)
155                         channel->reserve_arr[i] = channel->orig_arr[i];
156                 if (channel->free_arr != NULL)
157                         channel->free_arr[i] = NULL;
158                 if (channel->work_arr != NULL)
159                         channel->work_arr[i] = NULL;
160         }
161         channel->free_ptr = channel->length;
162         channel->reserve_ptr = channel->length;
163         channel->reserve_top = 0;
164         channel->post_index = 0;
165         channel->compl_index = 0;
166
167         return VXGE_HW_OK;
168 }
169
170 /*
171  * __vxge_hw_device_pci_e_init
172  * Initialize certain PCI/PCI-X configuration registers
173  * with recommended values. Save config space for future hw resets.
174  */
175 void
176 __vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev)
177 {
178         u16 cmd = 0;
179
180         /* Set the PErr Repconse bit and SERR in PCI command register. */
181         pci_read_config_word(hldev->pdev, PCI_COMMAND, &cmd);
182         cmd |= 0x140;
183         pci_write_config_word(hldev->pdev, PCI_COMMAND, cmd);
184
185         pci_save_state(hldev->pdev);
186
187         return;
188 }
189
190 /*
191  * __vxge_hw_device_register_poll
192  * Will poll certain register for specified amount of time.
193  * Will poll until masked bit is not cleared.
194  */
195 enum vxge_hw_status
196 __vxge_hw_device_register_poll(void __iomem *reg, u64 mask, u32 max_millis)
197 {
198         u64 val64;
199         u32 i = 0;
200         enum vxge_hw_status ret = VXGE_HW_FAIL;
201
202         udelay(10);
203
204         do {
205                 val64 = readq(reg);
206                 if (!(val64 & mask))
207                         return VXGE_HW_OK;
208                 udelay(100);
209         } while (++i <= 9);
210
211         i = 0;
212         do {
213                 val64 = readq(reg);
214                 if (!(val64 & mask))
215                         return VXGE_HW_OK;
216                 mdelay(1);
217         } while (++i <= max_millis);
218
219         return ret;
220 }
221
222  /* __vxge_hw_device_vpath_reset_in_prog_check - Check if vpath reset
223  * in progress
224  * This routine checks the vpath reset in progress register is turned zero
225  */
226 enum vxge_hw_status
227 __vxge_hw_device_vpath_reset_in_prog_check(u64 __iomem *vpath_rst_in_prog)
228 {
229         enum vxge_hw_status status;
230         status = __vxge_hw_device_register_poll(vpath_rst_in_prog,
231                         VXGE_HW_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(0x1ffff),
232                         VXGE_HW_DEF_DEVICE_POLL_MILLIS);
233         return status;
234 }
235
236 /*
237  * __vxge_hw_device_toc_get
238  * This routine sets the swapper and reads the toc pointer and returns the
239  * memory mapped address of the toc
240  */
241 struct vxge_hw_toc_reg __iomem *
242 __vxge_hw_device_toc_get(void __iomem *bar0)
243 {
244         u64 val64;
245         struct vxge_hw_toc_reg __iomem *toc = NULL;
246         enum vxge_hw_status status;
247
248         struct vxge_hw_legacy_reg __iomem *legacy_reg =
249                 (struct vxge_hw_legacy_reg __iomem *)bar0;
250
251         status = __vxge_hw_legacy_swapper_set(legacy_reg);
252         if (status != VXGE_HW_OK)
253                 goto exit;
254
255         val64 = readq(&legacy_reg->toc_first_pointer);
256         toc = (struct vxge_hw_toc_reg __iomem *)(bar0+val64);
257 exit:
258         return toc;
259 }
260
261 /*
262  * __vxge_hw_device_reg_addr_get
263  * This routine sets the swapper and reads the toc pointer and initializes the
264  * register location pointers in the device object. It waits until the ric is
265  * completed initializing registers.
266  */
267 enum vxge_hw_status
268 __vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev)
269 {
270         u64 val64;
271         u32 i;
272         enum vxge_hw_status status = VXGE_HW_OK;
273
274         hldev->legacy_reg = (struct vxge_hw_legacy_reg __iomem *)hldev->bar0;
275
276         hldev->toc_reg = __vxge_hw_device_toc_get(hldev->bar0);
277         if (hldev->toc_reg  == NULL) {
278                 status = VXGE_HW_FAIL;
279                 goto exit;
280         }
281
282         val64 = readq(&hldev->toc_reg->toc_common_pointer);
283         hldev->common_reg =
284         (struct vxge_hw_common_reg __iomem *)(hldev->bar0 + val64);
285
286         val64 = readq(&hldev->toc_reg->toc_mrpcim_pointer);
287         hldev->mrpcim_reg =
288                 (struct vxge_hw_mrpcim_reg __iomem *)(hldev->bar0 + val64);
289
290         for (i = 0; i < VXGE_HW_TITAN_SRPCIM_REG_SPACES; i++) {
291                 val64 = readq(&hldev->toc_reg->toc_srpcim_pointer[i]);
292                 hldev->srpcim_reg[i] =
293                         (struct vxge_hw_srpcim_reg __iomem *)
294                                 (hldev->bar0 + val64);
295         }
296
297         for (i = 0; i < VXGE_HW_TITAN_VPMGMT_REG_SPACES; i++) {
298                 val64 = readq(&hldev->toc_reg->toc_vpmgmt_pointer[i]);
299                 hldev->vpmgmt_reg[i] =
300                 (struct vxge_hw_vpmgmt_reg __iomem *)(hldev->bar0 + val64);
301         }
302
303         for (i = 0; i < VXGE_HW_TITAN_VPATH_REG_SPACES; i++) {
304                 val64 = readq(&hldev->toc_reg->toc_vpath_pointer[i]);
305                 hldev->vpath_reg[i] =
306                         (struct vxge_hw_vpath_reg __iomem *)
307                                 (hldev->bar0 + val64);
308         }
309
310         val64 = readq(&hldev->toc_reg->toc_kdfc);
311
312         switch (VXGE_HW_TOC_GET_KDFC_INITIAL_BIR(val64)) {
313         case 0:
314                 hldev->kdfc = (u8 __iomem *)(hldev->bar0 +
315                         VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val64));
316                 break;
317         default:
318                 break;
319         }
320
321         status = __vxge_hw_device_vpath_reset_in_prog_check(
322                         (u64 __iomem *)&hldev->common_reg->vpath_rst_in_prog);
323 exit:
324         return status;
325 }
326
327 /*
328  * __vxge_hw_device_id_get
329  * This routine returns sets the device id and revision numbers into the device
330  * structure
331  */
332 void __vxge_hw_device_id_get(struct __vxge_hw_device *hldev)
333 {
334         u64 val64;
335
336         val64 = readq(&hldev->common_reg->titan_asic_id);
337         hldev->device_id =
338                 (u16)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_DEVICE_ID(val64);
339
340         hldev->major_revision =
341                 (u8)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MAJOR_REVISION(val64);
342
343         hldev->minor_revision =
344                 (u8)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MINOR_REVISION(val64);
345
346         return;
347 }
348
349 /*
350  * __vxge_hw_device_access_rights_get: Get Access Rights of the driver
351  * This routine returns the Access Rights of the driver
352  */
353 static u32
354 __vxge_hw_device_access_rights_get(u32 host_type, u32 func_id)
355 {
356         u32 access_rights = VXGE_HW_DEVICE_ACCESS_RIGHT_VPATH;
357
358         switch (host_type) {
359         case VXGE_HW_NO_MR_NO_SR_NORMAL_FUNCTION:
360                 access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
361                                 VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
362                 break;
363         case VXGE_HW_MR_NO_SR_VH0_BASE_FUNCTION:
364                 access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
365                                 VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
366                 break;
367         case VXGE_HW_NO_MR_SR_VH0_FUNCTION0:
368                 access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
369                                 VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
370                 break;
371         case VXGE_HW_NO_MR_SR_VH0_VIRTUAL_FUNCTION:
372         case VXGE_HW_SR_VH_VIRTUAL_FUNCTION:
373         case VXGE_HW_MR_SR_VH0_INVALID_CONFIG:
374                 break;
375         case VXGE_HW_SR_VH_FUNCTION0:
376         case VXGE_HW_VH_NORMAL_FUNCTION:
377                 access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
378                 break;
379         }
380
381         return access_rights;
382 }
383 /*
384  * __vxge_hw_device_is_privilaged
385  * This routine checks if the device function is privilaged or not
386  */
387
388 enum vxge_hw_status
389 __vxge_hw_device_is_privilaged(u32 host_type, u32 func_id)
390 {
391         if (__vxge_hw_device_access_rights_get(host_type,
392                 func_id) &
393                 VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)
394                 return VXGE_HW_OK;
395         else
396                 return VXGE_HW_ERR_PRIVILAGED_OPEARATION;
397 }
398
399 /*
400  * __vxge_hw_device_host_info_get
401  * This routine returns the host type assignments
402  */
403 void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev)
404 {
405         u64 val64;
406         u32 i;
407
408         val64 = readq(&hldev->common_reg->host_type_assignments);
409
410         hldev->host_type =
411            (u32)VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64);
412
413         hldev->vpath_assignments = readq(&hldev->common_reg->vpath_assignments);
414
415         for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
416
417                 if (!(hldev->vpath_assignments & vxge_mBIT(i)))
418                         continue;
419
420                 hldev->func_id =
421                         __vxge_hw_vpath_func_id_get(i, hldev->vpmgmt_reg[i]);
422
423                 hldev->access_rights = __vxge_hw_device_access_rights_get(
424                         hldev->host_type, hldev->func_id);
425
426                 hldev->first_vp_id = i;
427                 break;
428         }
429
430         return;
431 }
432
433 /*
434  * __vxge_hw_verify_pci_e_info - Validate the pci-e link parameters such as
435  * link width and signalling rate.
436  */
437 static enum vxge_hw_status
438 __vxge_hw_verify_pci_e_info(struct __vxge_hw_device *hldev)
439 {
440         int exp_cap;
441         u16 lnk;
442
443         /* Get the negotiated link width and speed from PCI config space */
444         exp_cap = pci_find_capability(hldev->pdev, PCI_CAP_ID_EXP);
445         pci_read_config_word(hldev->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk);
446
447         if ((lnk & PCI_EXP_LNKSTA_CLS) != 1)
448                 return VXGE_HW_ERR_INVALID_PCI_INFO;
449
450         switch ((lnk & PCI_EXP_LNKSTA_NLW) >> 4) {
451         case PCIE_LNK_WIDTH_RESRV:
452         case PCIE_LNK_X1:
453         case PCIE_LNK_X2:
454         case PCIE_LNK_X4:
455         case PCIE_LNK_X8:
456                 break;
457         default:
458                 return VXGE_HW_ERR_INVALID_PCI_INFO;
459         }
460
461         return VXGE_HW_OK;
462 }
463
464 /*
465  * __vxge_hw_device_initialize
466  * Initialize Titan-V hardware.
467  */
468 enum vxge_hw_status __vxge_hw_device_initialize(struct __vxge_hw_device *hldev)
469 {
470         enum vxge_hw_status status = VXGE_HW_OK;
471
472         if (VXGE_HW_OK == __vxge_hw_device_is_privilaged(hldev->host_type,
473                                 hldev->func_id)) {
474                 /* Validate the pci-e link width and speed */
475                 status = __vxge_hw_verify_pci_e_info(hldev);
476                 if (status != VXGE_HW_OK)
477                         goto exit;
478         }
479
480 exit:
481         return status;
482 }
483
484 /**
485  * vxge_hw_device_hw_info_get - Get the hw information
486  * Returns the vpath mask that has the bits set for each vpath allocated
487  * for the driver, FW version information and the first mac addresse for
488  * each vpath
489  */
490 enum vxge_hw_status __devinit
491 vxge_hw_device_hw_info_get(void __iomem *bar0,
492                            struct vxge_hw_device_hw_info *hw_info)
493 {
494         u32 i;
495         u64 val64;
496         struct vxge_hw_toc_reg __iomem *toc;
497         struct vxge_hw_mrpcim_reg __iomem *mrpcim_reg;
498         struct vxge_hw_common_reg __iomem *common_reg;
499         struct vxge_hw_vpath_reg __iomem *vpath_reg;
500         struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg;
501         enum vxge_hw_status status;
502
503         memset(hw_info, 0, sizeof(struct vxge_hw_device_hw_info));
504
505         toc = __vxge_hw_device_toc_get(bar0);
506         if (toc == NULL) {
507                 status = VXGE_HW_ERR_CRITICAL;
508                 goto exit;
509         }
510
511         val64 = readq(&toc->toc_common_pointer);
512         common_reg = (struct vxge_hw_common_reg __iomem *)(bar0 + val64);
513
514         status = __vxge_hw_device_vpath_reset_in_prog_check(
515                 (u64 __iomem *)&common_reg->vpath_rst_in_prog);
516         if (status != VXGE_HW_OK)
517                 goto exit;
518
519         hw_info->vpath_mask = readq(&common_reg->vpath_assignments);
520
521         val64 = readq(&common_reg->host_type_assignments);
522
523         hw_info->host_type =
524            (u32)VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64);
525
526         for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
527
528                 if (!((hw_info->vpath_mask) & vxge_mBIT(i)))
529                         continue;
530
531                 val64 = readq(&toc->toc_vpmgmt_pointer[i]);
532
533                 vpmgmt_reg = (struct vxge_hw_vpmgmt_reg __iomem *)
534                                 (bar0 + val64);
535
536                 hw_info->func_id = __vxge_hw_vpath_func_id_get(i, vpmgmt_reg);
537                 if (__vxge_hw_device_access_rights_get(hw_info->host_type,
538                         hw_info->func_id) &
539                         VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM) {
540
541                         val64 = readq(&toc->toc_mrpcim_pointer);
542
543                         mrpcim_reg = (struct vxge_hw_mrpcim_reg __iomem *)
544                                         (bar0 + val64);
545
546                         writeq(0, &mrpcim_reg->xgmac_gen_fw_memo_mask);
547                         wmb();
548                 }
549
550                 val64 = readq(&toc->toc_vpath_pointer[i]);
551
552                 vpath_reg = (struct vxge_hw_vpath_reg __iomem *)(bar0 + val64);
553
554                 hw_info->function_mode =
555                         __vxge_hw_vpath_pci_func_mode_get(i, vpath_reg);
556
557                 status = __vxge_hw_vpath_fw_ver_get(i, vpath_reg, hw_info);
558                 if (status != VXGE_HW_OK)
559                         goto exit;
560
561                 status = __vxge_hw_vpath_card_info_get(i, vpath_reg, hw_info);
562                 if (status != VXGE_HW_OK)
563                         goto exit;
564
565                 break;
566         }
567
568         for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
569
570                 if (!((hw_info->vpath_mask) & vxge_mBIT(i)))
571                         continue;
572
573                 val64 = readq(&toc->toc_vpath_pointer[i]);
574                 vpath_reg = (struct vxge_hw_vpath_reg __iomem *)(bar0 + val64);
575
576                 status =  __vxge_hw_vpath_addr_get(i, vpath_reg,
577                                 hw_info->mac_addrs[i],
578                                 hw_info->mac_addr_masks[i]);
579                 if (status != VXGE_HW_OK)
580                         goto exit;
581         }
582 exit:
583         return status;
584 }
585
586 /*
587  * vxge_hw_device_initialize - Initialize Titan device.
588  * Initialize Titan device. Note that all the arguments of this public API
589  * are 'IN', including @hldev. Driver cooperates with
590  * OS to find new Titan device, locate its PCI and memory spaces.
591  *
592  * When done, the driver allocates sizeof(struct __vxge_hw_device) bytes for HW
593  * to enable the latter to perform Titan hardware initialization.
594  */
595 enum vxge_hw_status __devinit
596 vxge_hw_device_initialize(
597         struct __vxge_hw_device **devh,
598         struct vxge_hw_device_attr *attr,
599         struct vxge_hw_device_config *device_config)
600 {
601         u32 i;
602         u32 nblocks = 0;
603         struct __vxge_hw_device *hldev = NULL;
604         enum vxge_hw_status status = VXGE_HW_OK;
605
606         status = __vxge_hw_device_config_check(device_config);
607         if (status != VXGE_HW_OK)
608                 goto exit;
609
610         hldev = (struct __vxge_hw_device *)
611                         vmalloc(sizeof(struct __vxge_hw_device));
612         if (hldev == NULL) {
613                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
614                 goto exit;
615         }
616
617         memset(hldev, 0, sizeof(struct __vxge_hw_device));
618         hldev->magic = VXGE_HW_DEVICE_MAGIC;
619
620         vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_ALL);
621
622         /* apply config */
623         memcpy(&hldev->config, device_config,
624                 sizeof(struct vxge_hw_device_config));
625
626         hldev->bar0 = attr->bar0;
627         hldev->pdev = attr->pdev;
628
629         hldev->uld_callbacks.link_up = attr->uld_callbacks.link_up;
630         hldev->uld_callbacks.link_down = attr->uld_callbacks.link_down;
631         hldev->uld_callbacks.crit_err = attr->uld_callbacks.crit_err;
632
633         __vxge_hw_device_pci_e_init(hldev);
634
635         status = __vxge_hw_device_reg_addr_get(hldev);
636         if (status != VXGE_HW_OK)
637                 goto exit;
638         __vxge_hw_device_id_get(hldev);
639
640         __vxge_hw_device_host_info_get(hldev);
641
642         /* Incrementing for stats blocks */
643         nblocks++;
644
645         for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
646
647                 if (!(hldev->vpath_assignments & vxge_mBIT(i)))
648                         continue;
649
650                 if (device_config->vp_config[i].ring.enable ==
651                         VXGE_HW_RING_ENABLE)
652                         nblocks += device_config->vp_config[i].ring.ring_blocks;
653
654                 if (device_config->vp_config[i].fifo.enable ==
655                         VXGE_HW_FIFO_ENABLE)
656                         nblocks += device_config->vp_config[i].fifo.fifo_blocks;
657                 nblocks++;
658         }
659
660         if (__vxge_hw_blockpool_create(hldev,
661                 &hldev->block_pool,
662                 device_config->dma_blockpool_initial + nblocks,
663                 device_config->dma_blockpool_max + nblocks) != VXGE_HW_OK) {
664
665                 vxge_hw_device_terminate(hldev);
666                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
667                 goto exit;
668         }
669
670         status = __vxge_hw_device_initialize(hldev);
671
672         if (status != VXGE_HW_OK) {
673                 vxge_hw_device_terminate(hldev);
674                 goto exit;
675         }
676
677         *devh = hldev;
678 exit:
679         return status;
680 }
681
682 /*
683  * vxge_hw_device_terminate - Terminate Titan device.
684  * Terminate HW device.
685  */
686 void
687 vxge_hw_device_terminate(struct __vxge_hw_device *hldev)
688 {
689         vxge_assert(hldev->magic == VXGE_HW_DEVICE_MAGIC);
690
691         hldev->magic = VXGE_HW_DEVICE_DEAD;
692         __vxge_hw_blockpool_destroy(&hldev->block_pool);
693         vfree(hldev);
694 }
695
696 /*
697  * vxge_hw_device_stats_get - Get the device hw statistics.
698  * Returns the vpath h/w stats for the device.
699  */
700 enum vxge_hw_status
701 vxge_hw_device_stats_get(struct __vxge_hw_device *hldev,
702                         struct vxge_hw_device_stats_hw_info *hw_stats)
703 {
704         u32 i;
705         enum vxge_hw_status status = VXGE_HW_OK;
706
707         for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
708
709                 if (!(hldev->vpaths_deployed & vxge_mBIT(i)) ||
710                         (hldev->virtual_paths[i].vp_open ==
711                                 VXGE_HW_VP_NOT_OPEN))
712                         continue;
713
714                 memcpy(hldev->virtual_paths[i].hw_stats_sav,
715                                 hldev->virtual_paths[i].hw_stats,
716                                 sizeof(struct vxge_hw_vpath_stats_hw_info));
717
718                 status = __vxge_hw_vpath_stats_get(
719                         &hldev->virtual_paths[i],
720                         hldev->virtual_paths[i].hw_stats);
721         }
722
723         memcpy(hw_stats, &hldev->stats.hw_dev_info_stats,
724                         sizeof(struct vxge_hw_device_stats_hw_info));
725
726         return status;
727 }
728
729 /*
730  * vxge_hw_driver_stats_get - Get the device sw statistics.
731  * Returns the vpath s/w stats for the device.
732  */
733 enum vxge_hw_status vxge_hw_driver_stats_get(
734                         struct __vxge_hw_device *hldev,
735                         struct vxge_hw_device_stats_sw_info *sw_stats)
736 {
737         enum vxge_hw_status status = VXGE_HW_OK;
738
739         memcpy(sw_stats, &hldev->stats.sw_dev_info_stats,
740                 sizeof(struct vxge_hw_device_stats_sw_info));
741
742         return status;
743 }
744
745 /*
746  * vxge_hw_mrpcim_stats_access - Access the statistics from the given location
747  *                           and offset and perform an operation
748  * Get the statistics from the given location and offset.
749  */
750 enum vxge_hw_status
751 vxge_hw_mrpcim_stats_access(struct __vxge_hw_device *hldev,
752                             u32 operation, u32 location, u32 offset, u64 *stat)
753 {
754         u64 val64;
755         enum vxge_hw_status status = VXGE_HW_OK;
756
757         status = __vxge_hw_device_is_privilaged(hldev->host_type,
758                         hldev->func_id);
759         if (status != VXGE_HW_OK)
760                 goto exit;
761
762         val64 = VXGE_HW_XMAC_STATS_SYS_CMD_OP(operation) |
763                 VXGE_HW_XMAC_STATS_SYS_CMD_STROBE |
764                 VXGE_HW_XMAC_STATS_SYS_CMD_LOC_SEL(location) |
765                 VXGE_HW_XMAC_STATS_SYS_CMD_OFFSET_SEL(offset);
766
767         status = __vxge_hw_pio_mem_write64(val64,
768                                 &hldev->mrpcim_reg->xmac_stats_sys_cmd,
769                                 VXGE_HW_XMAC_STATS_SYS_CMD_STROBE,
770                                 hldev->config.device_poll_millis);
771
772         if ((status == VXGE_HW_OK) && (operation == VXGE_HW_STATS_OP_READ))
773                 *stat = readq(&hldev->mrpcim_reg->xmac_stats_sys_data);
774         else
775                 *stat = 0;
776 exit:
777         return status;
778 }
779
780 /*
781  * vxge_hw_device_xmac_aggr_stats_get - Get the Statistics on aggregate port
782  * Get the Statistics on aggregate port
783  */
784 enum vxge_hw_status
785 vxge_hw_device_xmac_aggr_stats_get(struct __vxge_hw_device *hldev, u32 port,
786                                    struct vxge_hw_xmac_aggr_stats *aggr_stats)
787 {
788         u64 *val64;
789         int i;
790         u32 offset = VXGE_HW_STATS_AGGRn_OFFSET;
791         enum vxge_hw_status status = VXGE_HW_OK;
792
793         val64 = (u64 *)aggr_stats;
794
795         status = __vxge_hw_device_is_privilaged(hldev->host_type,
796                         hldev->func_id);
797         if (status != VXGE_HW_OK)
798                 goto exit;
799
800         for (i = 0; i < sizeof(struct vxge_hw_xmac_aggr_stats) / 8; i++) {
801                 status = vxge_hw_mrpcim_stats_access(hldev,
802                                         VXGE_HW_STATS_OP_READ,
803                                         VXGE_HW_STATS_LOC_AGGR,
804                                         ((offset + (104 * port)) >> 3), val64);
805                 if (status != VXGE_HW_OK)
806                         goto exit;
807
808                 offset += 8;
809                 val64++;
810         }
811 exit:
812         return status;
813 }
814
815 /*
816  * vxge_hw_device_xmac_port_stats_get - Get the Statistics on a port
817  * Get the Statistics on port
818  */
819 enum vxge_hw_status
820 vxge_hw_device_xmac_port_stats_get(struct __vxge_hw_device *hldev, u32 port,
821                                    struct vxge_hw_xmac_port_stats *port_stats)
822 {
823         u64 *val64;
824         enum vxge_hw_status status = VXGE_HW_OK;
825         int i;
826         u32 offset = 0x0;
827         val64 = (u64 *) port_stats;
828
829         status = __vxge_hw_device_is_privilaged(hldev->host_type,
830                         hldev->func_id);
831         if (status != VXGE_HW_OK)
832                 goto exit;
833
834         for (i = 0; i < sizeof(struct vxge_hw_xmac_port_stats) / 8; i++) {
835                 status = vxge_hw_mrpcim_stats_access(hldev,
836                                         VXGE_HW_STATS_OP_READ,
837                                         VXGE_HW_STATS_LOC_AGGR,
838                                         ((offset + (608 * port)) >> 3), val64);
839                 if (status != VXGE_HW_OK)
840                         goto exit;
841
842                 offset += 8;
843                 val64++;
844         }
845
846 exit:
847         return status;
848 }
849
850 /*
851  * vxge_hw_device_xmac_stats_get - Get the XMAC Statistics
852  * Get the XMAC Statistics
853  */
854 enum vxge_hw_status
855 vxge_hw_device_xmac_stats_get(struct __vxge_hw_device *hldev,
856                               struct vxge_hw_xmac_stats *xmac_stats)
857 {
858         enum vxge_hw_status status = VXGE_HW_OK;
859         u32 i;
860
861         status = vxge_hw_device_xmac_aggr_stats_get(hldev,
862                                         0, &xmac_stats->aggr_stats[0]);
863
864         if (status != VXGE_HW_OK)
865                 goto exit;
866
867         status = vxge_hw_device_xmac_aggr_stats_get(hldev,
868                                 1, &xmac_stats->aggr_stats[1]);
869         if (status != VXGE_HW_OK)
870                 goto exit;
871
872         for (i = 0; i <= VXGE_HW_MAC_MAX_MAC_PORT_ID; i++) {
873
874                 status = vxge_hw_device_xmac_port_stats_get(hldev,
875                                         i, &xmac_stats->port_stats[i]);
876                 if (status != VXGE_HW_OK)
877                         goto exit;
878         }
879
880         for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
881
882                 if (!(hldev->vpaths_deployed & vxge_mBIT(i)))
883                         continue;
884
885                 status = __vxge_hw_vpath_xmac_tx_stats_get(
886                                         &hldev->virtual_paths[i],
887                                         &xmac_stats->vpath_tx_stats[i]);
888                 if (status != VXGE_HW_OK)
889                         goto exit;
890
891                 status = __vxge_hw_vpath_xmac_rx_stats_get(
892                                         &hldev->virtual_paths[i],
893                                         &xmac_stats->vpath_rx_stats[i]);
894                 if (status != VXGE_HW_OK)
895                         goto exit;
896         }
897 exit:
898         return status;
899 }
900
901 /*
902  * vxge_hw_device_debug_set - Set the debug module, level and timestamp
903  * This routine is used to dynamically change the debug output
904  */
905 void vxge_hw_device_debug_set(struct __vxge_hw_device *hldev,
906                               enum vxge_debug_level level, u32 mask)
907 {
908         if (hldev == NULL)
909                 return;
910
911 #if defined(VXGE_DEBUG_TRACE_MASK) || \
912         defined(VXGE_DEBUG_ERR_MASK)
913         hldev->debug_module_mask = mask;
914         hldev->debug_level = level;
915 #endif
916
917 #if defined(VXGE_DEBUG_ERR_MASK)
918         hldev->level_err = level & VXGE_ERR;
919 #endif
920
921 #if defined(VXGE_DEBUG_TRACE_MASK)
922         hldev->level_trace = level & VXGE_TRACE;
923 #endif
924 }
925
926 /*
927  * vxge_hw_device_error_level_get - Get the error level
928  * This routine returns the current error level set
929  */
930 u32 vxge_hw_device_error_level_get(struct __vxge_hw_device *hldev)
931 {
932 #if defined(VXGE_DEBUG_ERR_MASK)
933         if (hldev == NULL)
934                 return VXGE_ERR;
935         else
936                 return hldev->level_err;
937 #else
938         return 0;
939 #endif
940 }
941
942 /*
943  * vxge_hw_device_trace_level_get - Get the trace level
944  * This routine returns the current trace level set
945  */
946 u32 vxge_hw_device_trace_level_get(struct __vxge_hw_device *hldev)
947 {
948 #if defined(VXGE_DEBUG_TRACE_MASK)
949         if (hldev == NULL)
950                 return VXGE_TRACE;
951         else
952                 return hldev->level_trace;
953 #else
954         return 0;
955 #endif
956 }
957 /*
958  * vxge_hw_device_debug_mask_get - Get the debug mask
959  * This routine returns the current debug mask set
960  */
961 u32 vxge_hw_device_debug_mask_get(struct __vxge_hw_device *hldev)
962 {
963 #if defined(VXGE_DEBUG_TRACE_MASK) || defined(VXGE_DEBUG_ERR_MASK)
964         if (hldev == NULL)
965                 return 0;
966         return hldev->debug_module_mask;
967 #else
968         return 0;
969 #endif
970 }
971
972 /*
973  * vxge_hw_getpause_data -Pause frame frame generation and reception.
974  * Returns the Pause frame generation and reception capability of the NIC.
975  */
976 enum vxge_hw_status vxge_hw_device_getpause_data(struct __vxge_hw_device *hldev,
977                                                  u32 port, u32 *tx, u32 *rx)
978 {
979         u64 val64;
980         enum vxge_hw_status status = VXGE_HW_OK;
981
982         if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
983                 status = VXGE_HW_ERR_INVALID_DEVICE;
984                 goto exit;
985         }
986
987         if (port > VXGE_HW_MAC_MAX_MAC_PORT_ID) {
988                 status = VXGE_HW_ERR_INVALID_PORT;
989                 goto exit;
990         }
991
992         if (!(hldev->access_rights & VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) {
993                 status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
994                 goto exit;
995         }
996
997         val64 = readq(&hldev->mrpcim_reg->rxmac_pause_cfg_port[port]);
998         if (val64 & VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN)
999                 *tx = 1;
1000         if (val64 & VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN)
1001                 *rx = 1;
1002 exit:
1003         return status;
1004 }
1005
1006 /*
1007  * vxge_hw_device_setpause_data -  set/reset pause frame generation.
1008  * It can be used to set or reset Pause frame generation or reception
1009  * support of the NIC.
1010  */
1011
1012 enum vxge_hw_status vxge_hw_device_setpause_data(struct __vxge_hw_device *hldev,
1013                                                  u32 port, u32 tx, u32 rx)
1014 {
1015         u64 val64;
1016         enum vxge_hw_status status = VXGE_HW_OK;
1017
1018         if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
1019                 status = VXGE_HW_ERR_INVALID_DEVICE;
1020                 goto exit;
1021         }
1022
1023         if (port > VXGE_HW_MAC_MAX_MAC_PORT_ID) {
1024                 status = VXGE_HW_ERR_INVALID_PORT;
1025                 goto exit;
1026         }
1027
1028         status = __vxge_hw_device_is_privilaged(hldev->host_type,
1029                         hldev->func_id);
1030         if (status != VXGE_HW_OK)
1031                 goto exit;
1032
1033         val64 = readq(&hldev->mrpcim_reg->rxmac_pause_cfg_port[port]);
1034         if (tx)
1035                 val64 |= VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN;
1036         else
1037                 val64 &= ~VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN;
1038         if (rx)
1039                 val64 |= VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN;
1040         else
1041                 val64 &= ~VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN;
1042
1043         writeq(val64, &hldev->mrpcim_reg->rxmac_pause_cfg_port[port]);
1044 exit:
1045         return status;
1046 }
1047
1048 u16 vxge_hw_device_link_width_get(struct __vxge_hw_device *hldev)
1049 {
1050         int link_width, exp_cap;
1051         u16 lnk;
1052
1053         exp_cap = pci_find_capability(hldev->pdev, PCI_CAP_ID_EXP);
1054         pci_read_config_word(hldev->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk);
1055         link_width = (lnk & VXGE_HW_PCI_EXP_LNKCAP_LNK_WIDTH) >> 4;
1056         return link_width;
1057 }
1058
1059 /*
1060  * __vxge_hw_ring_block_memblock_idx - Return the memblock index
1061  * This function returns the index of memory block
1062  */
1063 static inline u32
1064 __vxge_hw_ring_block_memblock_idx(u8 *block)
1065 {
1066         return (u32)*((u64 *)(block + VXGE_HW_RING_MEMBLOCK_IDX_OFFSET));
1067 }
1068
1069 /*
1070  * __vxge_hw_ring_block_memblock_idx_set - Sets the memblock index
1071  * This function sets index to a memory block
1072  */
1073 static inline void
1074 __vxge_hw_ring_block_memblock_idx_set(u8 *block, u32 memblock_idx)
1075 {
1076         *((u64 *)(block + VXGE_HW_RING_MEMBLOCK_IDX_OFFSET)) = memblock_idx;
1077 }
1078
1079 /*
1080  * __vxge_hw_ring_block_next_pointer_set - Sets the next block pointer
1081  * in RxD block
1082  * Sets the next block pointer in RxD block
1083  */
1084 static inline void
1085 __vxge_hw_ring_block_next_pointer_set(u8 *block, dma_addr_t dma_next)
1086 {
1087         *((u64 *)(block + VXGE_HW_RING_NEXT_BLOCK_POINTER_OFFSET)) = dma_next;
1088 }
1089
1090 /*
1091  * __vxge_hw_ring_first_block_address_get - Returns the dma address of the
1092  *             first block
1093  * Returns the dma address of the first RxD block
1094  */
1095 u64 __vxge_hw_ring_first_block_address_get(struct __vxge_hw_ring *ring)
1096 {
1097         struct vxge_hw_mempool_dma *dma_object;
1098
1099         dma_object = ring->mempool->memblocks_dma_arr;
1100         vxge_assert(dma_object != NULL);
1101
1102         return dma_object->addr;
1103 }
1104
1105 /*
1106  * __vxge_hw_ring_item_dma_addr - Return the dma address of an item
1107  * This function returns the dma address of a given item
1108  */
1109 static dma_addr_t __vxge_hw_ring_item_dma_addr(struct vxge_hw_mempool *mempoolh,
1110                                                void *item)
1111 {
1112         u32 memblock_idx;
1113         void *memblock;
1114         struct vxge_hw_mempool_dma *memblock_dma_object;
1115         ptrdiff_t dma_item_offset;
1116
1117         /* get owner memblock index */
1118         memblock_idx = __vxge_hw_ring_block_memblock_idx(item);
1119
1120         /* get owner memblock by memblock index */
1121         memblock = mempoolh->memblocks_arr[memblock_idx];
1122
1123         /* get memblock DMA object by memblock index */
1124         memblock_dma_object = mempoolh->memblocks_dma_arr + memblock_idx;
1125
1126         /* calculate offset in the memblock of this item */
1127         dma_item_offset = (u8 *)item - (u8 *)memblock;
1128
1129         return memblock_dma_object->addr + dma_item_offset;
1130 }
1131
1132 /*
1133  * __vxge_hw_ring_rxdblock_link - Link the RxD blocks
1134  * This function returns the dma address of a given item
1135  */
1136 static void __vxge_hw_ring_rxdblock_link(struct vxge_hw_mempool *mempoolh,
1137                                          struct __vxge_hw_ring *ring, u32 from,
1138                                          u32 to)
1139 {
1140         u8 *to_item , *from_item;
1141         dma_addr_t to_dma;
1142
1143         /* get "from" RxD block */
1144         from_item = mempoolh->items_arr[from];
1145         vxge_assert(from_item);
1146
1147         /* get "to" RxD block */
1148         to_item = mempoolh->items_arr[to];
1149         vxge_assert(to_item);
1150
1151         /* return address of the beginning of previous RxD block */
1152         to_dma = __vxge_hw_ring_item_dma_addr(mempoolh, to_item);
1153
1154         /* set next pointer for this RxD block to point on
1155          * previous item's DMA start address */
1156         __vxge_hw_ring_block_next_pointer_set(from_item, to_dma);
1157 }
1158
1159 /*
1160  * __vxge_hw_ring_mempool_item_alloc - Allocate List blocks for RxD
1161  * block callback
1162  * This function is callback passed to __vxge_hw_mempool_create to create memory
1163  * pool for RxD block
1164  */
1165 static void
1166 __vxge_hw_ring_mempool_item_alloc(struct vxge_hw_mempool *mempoolh,
1167                                   u32 memblock_index,
1168                                   struct vxge_hw_mempool_dma *dma_object,
1169                                   u32 index, u32 is_last)
1170 {
1171         u32 i;
1172         void *item = mempoolh->items_arr[index];
1173         struct __vxge_hw_ring *ring =
1174                 (struct __vxge_hw_ring *)mempoolh->userdata;
1175
1176         /* format rxds array */
1177         for (i = 0; i < ring->rxds_per_block; i++) {
1178                 void *rxdblock_priv;
1179                 void *uld_priv;
1180                 struct vxge_hw_ring_rxd_1 *rxdp;
1181
1182                 u32 reserve_index = ring->channel.reserve_ptr -
1183                                 (index * ring->rxds_per_block + i + 1);
1184                 u32 memblock_item_idx;
1185
1186                 ring->channel.reserve_arr[reserve_index] = ((u8 *)item) +
1187                                                 i * ring->rxd_size;
1188
1189                 /* Note: memblock_item_idx is index of the item within
1190                  *       the memblock. For instance, in case of three RxD-blocks
1191                  *       per memblock this value can be 0, 1 or 2. */
1192                 rxdblock_priv = __vxge_hw_mempool_item_priv(mempoolh,
1193                                         memblock_index, item,
1194                                         &memblock_item_idx);
1195
1196                 rxdp = (struct vxge_hw_ring_rxd_1 *)
1197                                 ring->channel.reserve_arr[reserve_index];
1198
1199                 uld_priv = ((u8 *)rxdblock_priv + ring->rxd_priv_size * i);
1200
1201                 /* pre-format Host_Control */
1202                 rxdp->host_control = (u64)(size_t)uld_priv;
1203         }
1204
1205         __vxge_hw_ring_block_memblock_idx_set(item, memblock_index);
1206
1207         if (is_last) {
1208                 /* link last one with first one */
1209                 __vxge_hw_ring_rxdblock_link(mempoolh, ring, index, 0);
1210         }
1211
1212         if (index > 0) {
1213                 /* link this RxD block with previous one */
1214                 __vxge_hw_ring_rxdblock_link(mempoolh, ring, index - 1, index);
1215         }
1216
1217         return;
1218 }
1219
1220 /*
1221  * __vxge_hw_ring_initial_replenish - Initial replenish of RxDs
1222  * This function replenishes the RxDs from reserve array to work array
1223  */
1224 enum vxge_hw_status
1225 vxge_hw_ring_replenish(struct __vxge_hw_ring *ring, u16 min_flag)
1226 {
1227         void *rxd;
1228         int i = 0;
1229         struct __vxge_hw_channel *channel;
1230         enum vxge_hw_status status = VXGE_HW_OK;
1231
1232         channel = &ring->channel;
1233
1234         while (vxge_hw_channel_dtr_count(channel) > 0) {
1235
1236                 status = vxge_hw_ring_rxd_reserve(ring, &rxd);
1237
1238                 vxge_assert(status == VXGE_HW_OK);
1239
1240                 if (ring->rxd_init) {
1241                         status = ring->rxd_init(rxd, channel->userdata);
1242                         if (status != VXGE_HW_OK) {
1243                                 vxge_hw_ring_rxd_free(ring, rxd);
1244                                 goto exit;
1245                         }
1246                 }
1247
1248                 vxge_hw_ring_rxd_post(ring, rxd);
1249                 if (min_flag) {
1250                         i++;
1251                         if (i == VXGE_HW_RING_MIN_BUFF_ALLOCATION)
1252                                 break;
1253                 }
1254         }
1255         status = VXGE_HW_OK;
1256 exit:
1257         return status;
1258 }
1259
1260 /*
1261  * __vxge_hw_ring_create - Create a Ring
1262  * This function creates Ring and initializes it.
1263  *
1264  */
1265 enum vxge_hw_status
1266 __vxge_hw_ring_create(struct __vxge_hw_vpath_handle *vp,
1267                       struct vxge_hw_ring_attr *attr)
1268 {
1269         enum vxge_hw_status status = VXGE_HW_OK;
1270         struct __vxge_hw_ring *ring;
1271         u32 ring_length;
1272         struct vxge_hw_ring_config *config;
1273         struct __vxge_hw_device *hldev;
1274         u32 vp_id;
1275         struct vxge_hw_mempool_cbs ring_mp_callback;
1276
1277         if ((vp == NULL) || (attr == NULL)) {
1278                 status = VXGE_HW_FAIL;
1279                 goto exit;
1280         }
1281
1282         hldev = vp->vpath->hldev;
1283         vp_id = vp->vpath->vp_id;
1284
1285         config = &hldev->config.vp_config[vp_id].ring;
1286
1287         ring_length = config->ring_blocks *
1288                         vxge_hw_ring_rxds_per_block_get(config->buffer_mode);
1289
1290         ring = (struct __vxge_hw_ring *)__vxge_hw_channel_allocate(vp,
1291                                                 VXGE_HW_CHANNEL_TYPE_RING,
1292                                                 ring_length,
1293                                                 attr->per_rxd_space,
1294                                                 attr->userdata);
1295
1296         if (ring == NULL) {
1297                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
1298                 goto exit;
1299         }
1300
1301         vp->vpath->ringh = ring;
1302         ring->vp_id = vp_id;
1303         ring->vp_reg = vp->vpath->vp_reg;
1304         ring->common_reg = hldev->common_reg;
1305         ring->stats = &vp->vpath->sw_stats->ring_stats;
1306         ring->config = config;
1307         ring->callback = attr->callback;
1308         ring->rxd_init = attr->rxd_init;
1309         ring->rxd_term = attr->rxd_term;
1310         ring->buffer_mode = config->buffer_mode;
1311         ring->rxds_limit = config->rxds_limit;
1312
1313         ring->rxd_size = vxge_hw_ring_rxd_size_get(config->buffer_mode);
1314         ring->rxd_priv_size =
1315                 sizeof(struct __vxge_hw_ring_rxd_priv) + attr->per_rxd_space;
1316         ring->per_rxd_space = attr->per_rxd_space;
1317
1318         ring->rxd_priv_size =
1319                 ((ring->rxd_priv_size + VXGE_CACHE_LINE_SIZE - 1) /
1320                 VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE;
1321
1322         /* how many RxDs can fit into one block. Depends on configured
1323          * buffer_mode. */
1324         ring->rxds_per_block =
1325                 vxge_hw_ring_rxds_per_block_get(config->buffer_mode);
1326
1327         /* calculate actual RxD block private size */
1328         ring->rxdblock_priv_size = ring->rxd_priv_size * ring->rxds_per_block;
1329         ring_mp_callback.item_func_alloc = __vxge_hw_ring_mempool_item_alloc;
1330         ring->mempool = __vxge_hw_mempool_create(hldev,
1331                                 VXGE_HW_BLOCK_SIZE,
1332                                 VXGE_HW_BLOCK_SIZE,
1333                                 ring->rxdblock_priv_size,
1334                                 ring->config->ring_blocks,
1335                                 ring->config->ring_blocks,
1336                                 &ring_mp_callback,
1337                                 ring);
1338
1339         if (ring->mempool == NULL) {
1340                 __vxge_hw_ring_delete(vp);
1341                 return VXGE_HW_ERR_OUT_OF_MEMORY;
1342         }
1343
1344         status = __vxge_hw_channel_initialize(&ring->channel);
1345         if (status != VXGE_HW_OK) {
1346                 __vxge_hw_ring_delete(vp);
1347                 goto exit;
1348         }
1349
1350         /* Note:
1351          * Specifying rxd_init callback means two things:
1352          * 1) rxds need to be initialized by driver at channel-open time;
1353          * 2) rxds need to be posted at channel-open time
1354          *    (that's what the initial_replenish() below does)
1355          * Currently we don't have a case when the 1) is done without the 2).
1356          */
1357         if (ring->rxd_init) {
1358                 status = vxge_hw_ring_replenish(ring, 1);
1359                 if (status != VXGE_HW_OK) {
1360                         __vxge_hw_ring_delete(vp);
1361                         goto exit;
1362                 }
1363         }
1364
1365         /* initial replenish will increment the counter in its post() routine,
1366          * we have to reset it */
1367         ring->stats->common_stats.usage_cnt = 0;
1368 exit:
1369         return status;
1370 }
1371
1372 /*
1373  * __vxge_hw_ring_abort - Returns the RxD
1374  * This function terminates the RxDs of ring
1375  */
1376 enum vxge_hw_status __vxge_hw_ring_abort(struct __vxge_hw_ring *ring)
1377 {
1378         void *rxdh;
1379         struct __vxge_hw_channel *channel;
1380
1381         channel = &ring->channel;
1382
1383         for (;;) {
1384                 vxge_hw_channel_dtr_try_complete(channel, &rxdh);
1385
1386                 if (rxdh == NULL)
1387                         break;
1388
1389                 vxge_hw_channel_dtr_complete(channel);
1390
1391                 if (ring->rxd_term)
1392                         ring->rxd_term(rxdh, VXGE_HW_RXD_STATE_POSTED,
1393                                 channel->userdata);
1394
1395                 vxge_hw_channel_dtr_free(channel, rxdh);
1396         }
1397
1398         return VXGE_HW_OK;
1399 }
1400
1401 /*
1402  * __vxge_hw_ring_reset - Resets the ring
1403  * This function resets the ring during vpath reset operation
1404  */
1405 enum vxge_hw_status __vxge_hw_ring_reset(struct __vxge_hw_ring *ring)
1406 {
1407         enum vxge_hw_status status = VXGE_HW_OK;
1408         struct __vxge_hw_channel *channel;
1409
1410         channel = &ring->channel;
1411
1412         __vxge_hw_ring_abort(ring);
1413
1414         status = __vxge_hw_channel_reset(channel);
1415
1416         if (status != VXGE_HW_OK)
1417                 goto exit;
1418
1419         if (ring->rxd_init) {
1420                 status = vxge_hw_ring_replenish(ring, 1);
1421                 if (status != VXGE_HW_OK)
1422                         goto exit;
1423         }
1424 exit:
1425         return status;
1426 }
1427
1428 /*
1429  * __vxge_hw_ring_delete - Removes the ring
1430  * This function freeup the memory pool and removes the ring
1431  */
1432 enum vxge_hw_status __vxge_hw_ring_delete(struct __vxge_hw_vpath_handle *vp)
1433 {
1434         struct __vxge_hw_ring *ring = vp->vpath->ringh;
1435
1436         __vxge_hw_ring_abort(ring);
1437
1438         if (ring->mempool)
1439                 __vxge_hw_mempool_destroy(ring->mempool);
1440
1441         vp->vpath->ringh = NULL;
1442         __vxge_hw_channel_free(&ring->channel);
1443
1444         return VXGE_HW_OK;
1445 }
1446
1447 /*
1448  * __vxge_hw_mempool_grow
1449  * Will resize mempool up to %num_allocate value.
1450  */
1451 enum vxge_hw_status
1452 __vxge_hw_mempool_grow(struct vxge_hw_mempool *mempool, u32 num_allocate,
1453                        u32 *num_allocated)
1454 {
1455         u32 i, first_time = mempool->memblocks_allocated == 0 ? 1 : 0;
1456         u32 n_items = mempool->items_per_memblock;
1457         u32 start_block_idx = mempool->memblocks_allocated;
1458         u32 end_block_idx = mempool->memblocks_allocated + num_allocate;
1459         enum vxge_hw_status status = VXGE_HW_OK;
1460
1461         *num_allocated = 0;
1462
1463         if (end_block_idx > mempool->memblocks_max) {
1464                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
1465                 goto exit;
1466         }
1467
1468         for (i = start_block_idx; i < end_block_idx; i++) {
1469                 u32 j;
1470                 u32 is_last = ((end_block_idx - 1) == i);
1471                 struct vxge_hw_mempool_dma *dma_object =
1472                         mempool->memblocks_dma_arr + i;
1473                 void *the_memblock;
1474
1475                 /* allocate memblock's private part. Each DMA memblock
1476                  * has a space allocated for item's private usage upon
1477                  * mempool's user request. Each time mempool grows, it will
1478                  * allocate new memblock and its private part at once.
1479                  * This helps to minimize memory usage a lot. */
1480                 mempool->memblocks_priv_arr[i] =
1481                                 vmalloc(mempool->items_priv_size * n_items);
1482                 if (mempool->memblocks_priv_arr[i] == NULL) {
1483                         status = VXGE_HW_ERR_OUT_OF_MEMORY;
1484                         goto exit;
1485                 }
1486
1487                 memset(mempool->memblocks_priv_arr[i], 0,
1488                              mempool->items_priv_size * n_items);
1489
1490                 /* allocate DMA-capable memblock */
1491                 mempool->memblocks_arr[i] =
1492                         __vxge_hw_blockpool_malloc(mempool->devh,
1493                                 mempool->memblock_size, dma_object);
1494                 if (mempool->memblocks_arr[i] == NULL) {
1495                         vfree(mempool->memblocks_priv_arr[i]);
1496                         status = VXGE_HW_ERR_OUT_OF_MEMORY;
1497                         goto exit;
1498                 }
1499
1500                 (*num_allocated)++;
1501                 mempool->memblocks_allocated++;
1502
1503                 memset(mempool->memblocks_arr[i], 0, mempool->memblock_size);
1504
1505                 the_memblock = mempool->memblocks_arr[i];
1506
1507                 /* fill the items hash array */
1508                 for (j = 0; j < n_items; j++) {
1509                         u32 index = i * n_items + j;
1510
1511                         if (first_time && index >= mempool->items_initial)
1512                                 break;
1513
1514                         mempool->items_arr[index] =
1515                                 ((char *)the_memblock + j*mempool->item_size);
1516
1517                         /* let caller to do more job on each item */
1518                         if (mempool->item_func_alloc != NULL)
1519                                 mempool->item_func_alloc(mempool, i,
1520                                         dma_object, index, is_last);
1521
1522                         mempool->items_current = index + 1;
1523                 }
1524
1525                 if (first_time && mempool->items_current ==
1526                                         mempool->items_initial)
1527                         break;
1528         }
1529 exit:
1530         return status;
1531 }
1532
1533 /*
1534  * vxge_hw_mempool_create
1535  * This function will create memory pool object. Pool may grow but will
1536  * never shrink. Pool consists of number of dynamically allocated blocks
1537  * with size enough to hold %items_initial number of items. Memory is
1538  * DMA-able but client must map/unmap before interoperating with the device.
1539  */
1540 struct vxge_hw_mempool*
1541 __vxge_hw_mempool_create(
1542         struct __vxge_hw_device *devh,
1543         u32 memblock_size,
1544         u32 item_size,
1545         u32 items_priv_size,
1546         u32 items_initial,
1547         u32 items_max,
1548         struct vxge_hw_mempool_cbs *mp_callback,
1549         void *userdata)
1550 {
1551         enum vxge_hw_status status = VXGE_HW_OK;
1552         u32 memblocks_to_allocate;
1553         struct vxge_hw_mempool *mempool = NULL;
1554         u32 allocated;
1555
1556         if (memblock_size < item_size) {
1557                 status = VXGE_HW_FAIL;
1558                 goto exit;
1559         }
1560
1561         mempool = (struct vxge_hw_mempool *)
1562                         vmalloc(sizeof(struct vxge_hw_mempool));
1563         if (mempool == NULL) {
1564                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
1565                 goto exit;
1566         }
1567         memset(mempool, 0, sizeof(struct vxge_hw_mempool));
1568
1569         mempool->devh                   = devh;
1570         mempool->memblock_size          = memblock_size;
1571         mempool->items_max              = items_max;
1572         mempool->items_initial          = items_initial;
1573         mempool->item_size              = item_size;
1574         mempool->items_priv_size        = items_priv_size;
1575         mempool->item_func_alloc        = mp_callback->item_func_alloc;
1576         mempool->userdata               = userdata;
1577
1578         mempool->memblocks_allocated = 0;
1579
1580         mempool->items_per_memblock = memblock_size / item_size;
1581
1582         mempool->memblocks_max = (items_max + mempool->items_per_memblock - 1) /
1583                                         mempool->items_per_memblock;
1584
1585         /* allocate array of memblocks */
1586         mempool->memblocks_arr =
1587                 (void **) vmalloc(sizeof(void *) * mempool->memblocks_max);
1588         if (mempool->memblocks_arr == NULL) {
1589                 __vxge_hw_mempool_destroy(mempool);
1590                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
1591                 mempool = NULL;
1592                 goto exit;
1593         }
1594         memset(mempool->memblocks_arr, 0,
1595                 sizeof(void *) * mempool->memblocks_max);
1596
1597         /* allocate array of private parts of items per memblocks */
1598         mempool->memblocks_priv_arr =
1599                 (void **) vmalloc(sizeof(void *) * mempool->memblocks_max);
1600         if (mempool->memblocks_priv_arr == NULL) {
1601                 __vxge_hw_mempool_destroy(mempool);
1602                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
1603                 mempool = NULL;
1604                 goto exit;
1605         }
1606         memset(mempool->memblocks_priv_arr, 0,
1607                     sizeof(void *) * mempool->memblocks_max);
1608
1609         /* allocate array of memblocks DMA objects */
1610         mempool->memblocks_dma_arr = (struct vxge_hw_mempool_dma *)
1611                 vmalloc(sizeof(struct vxge_hw_mempool_dma) *
1612                         mempool->memblocks_max);
1613
1614         if (mempool->memblocks_dma_arr == NULL) {
1615                 __vxge_hw_mempool_destroy(mempool);
1616                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
1617                 mempool = NULL;
1618                 goto exit;
1619         }
1620         memset(mempool->memblocks_dma_arr, 0,
1621                         sizeof(struct vxge_hw_mempool_dma) *
1622                         mempool->memblocks_max);
1623
1624         /* allocate hash array of items */
1625         mempool->items_arr =
1626                 (void **) vmalloc(sizeof(void *) * mempool->items_max);
1627         if (mempool->items_arr == NULL) {
1628                 __vxge_hw_mempool_destroy(mempool);
1629                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
1630                 mempool = NULL;
1631                 goto exit;
1632         }
1633         memset(mempool->items_arr, 0, sizeof(void *) * mempool->items_max);
1634
1635         /* calculate initial number of memblocks */
1636         memblocks_to_allocate = (mempool->items_initial +
1637                                  mempool->items_per_memblock - 1) /
1638                                                 mempool->items_per_memblock;
1639
1640         /* pre-allocate the mempool */
1641         status = __vxge_hw_mempool_grow(mempool, memblocks_to_allocate,
1642                                         &allocated);
1643         if (status != VXGE_HW_OK) {
1644                 __vxge_hw_mempool_destroy(mempool);
1645                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
1646                 mempool = NULL;
1647                 goto exit;
1648         }
1649
1650 exit:
1651         return mempool;
1652 }
1653
1654 /*
1655  * vxge_hw_mempool_destroy
1656  */
1657 void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool)
1658 {
1659         u32 i, j;
1660         struct __vxge_hw_device *devh = mempool->devh;
1661
1662         for (i = 0; i < mempool->memblocks_allocated; i++) {
1663                 struct vxge_hw_mempool_dma *dma_object;
1664
1665                 vxge_assert(mempool->memblocks_arr[i]);
1666                 vxge_assert(mempool->memblocks_dma_arr + i);
1667
1668                 dma_object = mempool->memblocks_dma_arr + i;
1669
1670                 for (j = 0; j < mempool->items_per_memblock; j++) {
1671                         u32 index = i * mempool->items_per_memblock + j;
1672
1673                         /* to skip last partially filled(if any) memblock */
1674                         if (index >= mempool->items_current)
1675                                 break;
1676                 }
1677
1678                 vfree(mempool->memblocks_priv_arr[i]);
1679
1680                 __vxge_hw_blockpool_free(devh, mempool->memblocks_arr[i],
1681                                 mempool->memblock_size, dma_object);
1682         }
1683
1684         vfree(mempool->items_arr);
1685
1686         vfree(mempool->memblocks_dma_arr);
1687
1688         vfree(mempool->memblocks_priv_arr);
1689
1690         vfree(mempool->memblocks_arr);
1691
1692         vfree(mempool);
1693 }
1694
1695 /*
1696  * __vxge_hw_device_fifo_config_check - Check fifo configuration.
1697  * Check the fifo configuration
1698  */
1699 enum vxge_hw_status
1700 __vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config)
1701 {
1702         if ((fifo_config->fifo_blocks < VXGE_HW_MIN_FIFO_BLOCKS) ||
1703              (fifo_config->fifo_blocks > VXGE_HW_MAX_FIFO_BLOCKS))
1704                 return VXGE_HW_BADCFG_FIFO_BLOCKS;
1705
1706         return VXGE_HW_OK;
1707 }
1708
1709 /*
1710  * __vxge_hw_device_vpath_config_check - Check vpath configuration.
1711  * Check the vpath configuration
1712  */
1713 enum vxge_hw_status
1714 __vxge_hw_device_vpath_config_check(struct vxge_hw_vp_config *vp_config)
1715 {
1716         enum vxge_hw_status status;
1717
1718         if ((vp_config->min_bandwidth < VXGE_HW_VPATH_BANDWIDTH_MIN) ||
1719                 (vp_config->min_bandwidth >
1720                                         VXGE_HW_VPATH_BANDWIDTH_MAX))
1721                 return VXGE_HW_BADCFG_VPATH_MIN_BANDWIDTH;
1722
1723         status = __vxge_hw_device_fifo_config_check(&vp_config->fifo);
1724         if (status != VXGE_HW_OK)
1725                 return status;
1726
1727         if ((vp_config->mtu != VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU) &&
1728                 ((vp_config->mtu < VXGE_HW_VPATH_MIN_INITIAL_MTU) ||
1729                 (vp_config->mtu > VXGE_HW_VPATH_MAX_INITIAL_MTU)))
1730                 return VXGE_HW_BADCFG_VPATH_MTU;
1731
1732         if ((vp_config->rpa_strip_vlan_tag !=
1733                 VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT) &&
1734                 (vp_config->rpa_strip_vlan_tag !=
1735                 VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE) &&
1736                 (vp_config->rpa_strip_vlan_tag !=
1737                 VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_DISABLE))
1738                 return VXGE_HW_BADCFG_VPATH_RPA_STRIP_VLAN_TAG;
1739
1740         return VXGE_HW_OK;
1741 }
1742
1743 /*
1744  * __vxge_hw_device_config_check - Check device configuration.
1745  * Check the device configuration
1746  */
1747 enum vxge_hw_status
1748 __vxge_hw_device_config_check(struct vxge_hw_device_config *new_config)
1749 {
1750         u32 i;
1751         enum vxge_hw_status status;
1752
1753         if ((new_config->intr_mode != VXGE_HW_INTR_MODE_IRQLINE) &&
1754            (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX) &&
1755            (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) &&
1756            (new_config->intr_mode != VXGE_HW_INTR_MODE_DEF))
1757                 return VXGE_HW_BADCFG_INTR_MODE;
1758
1759         if ((new_config->rts_mac_en != VXGE_HW_RTS_MAC_DISABLE) &&
1760            (new_config->rts_mac_en != VXGE_HW_RTS_MAC_ENABLE))
1761                 return VXGE_HW_BADCFG_RTS_MAC_EN;
1762
1763         for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
1764                 status = __vxge_hw_device_vpath_config_check(
1765                                 &new_config->vp_config[i]);
1766                 if (status != VXGE_HW_OK)
1767                         return status;
1768         }
1769
1770         return VXGE_HW_OK;
1771 }
1772
1773 /*
1774  * vxge_hw_device_config_default_get - Initialize device config with defaults.
1775  * Initialize Titan device config with default values.
1776  */
1777 enum vxge_hw_status __devinit
1778 vxge_hw_device_config_default_get(struct vxge_hw_device_config *device_config)
1779 {
1780         u32 i;
1781
1782         device_config->dma_blockpool_initial =
1783                                         VXGE_HW_INITIAL_DMA_BLOCK_POOL_SIZE;
1784         device_config->dma_blockpool_max = VXGE_HW_MAX_DMA_BLOCK_POOL_SIZE;
1785         device_config->intr_mode = VXGE_HW_INTR_MODE_DEF;
1786         device_config->rth_en = VXGE_HW_RTH_DEFAULT;
1787         device_config->rth_it_type = VXGE_HW_RTH_IT_TYPE_DEFAULT;
1788         device_config->device_poll_millis =  VXGE_HW_DEF_DEVICE_POLL_MILLIS;
1789         device_config->rts_mac_en =  VXGE_HW_RTS_MAC_DEFAULT;
1790
1791         for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
1792
1793                 device_config->vp_config[i].vp_id = i;
1794
1795                 device_config->vp_config[i].min_bandwidth =
1796                                 VXGE_HW_VPATH_BANDWIDTH_DEFAULT;
1797
1798                 device_config->vp_config[i].ring.enable = VXGE_HW_RING_DEFAULT;
1799
1800                 device_config->vp_config[i].ring.ring_blocks =
1801                                 VXGE_HW_DEF_RING_BLOCKS;
1802
1803                 device_config->vp_config[i].ring.buffer_mode =
1804                                 VXGE_HW_RING_RXD_BUFFER_MODE_DEFAULT;
1805
1806                 device_config->vp_config[i].ring.scatter_mode =
1807                                 VXGE_HW_RING_SCATTER_MODE_USE_FLASH_DEFAULT;
1808
1809                 device_config->vp_config[i].ring.rxds_limit =
1810                                 VXGE_HW_DEF_RING_RXDS_LIMIT;
1811
1812                 device_config->vp_config[i].fifo.enable = VXGE_HW_FIFO_ENABLE;
1813
1814                 device_config->vp_config[i].fifo.fifo_blocks =
1815                                 VXGE_HW_MIN_FIFO_BLOCKS;
1816
1817                 device_config->vp_config[i].fifo.max_frags =
1818                                 VXGE_HW_MAX_FIFO_FRAGS;
1819
1820                 device_config->vp_config[i].fifo.memblock_size =
1821                                 VXGE_HW_DEF_FIFO_MEMBLOCK_SIZE;
1822
1823                 device_config->vp_config[i].fifo.alignment_size =
1824                                 VXGE_HW_DEF_FIFO_ALIGNMENT_SIZE;
1825
1826                 device_config->vp_config[i].fifo.intr =
1827                                 VXGE_HW_FIFO_QUEUE_INTR_DEFAULT;
1828
1829                 device_config->vp_config[i].fifo.no_snoop_bits =
1830                                 VXGE_HW_FIFO_NO_SNOOP_DEFAULT;
1831                 device_config->vp_config[i].tti.intr_enable =
1832                                 VXGE_HW_TIM_INTR_DEFAULT;
1833
1834                 device_config->vp_config[i].tti.btimer_val =
1835                                 VXGE_HW_USE_FLASH_DEFAULT;
1836
1837                 device_config->vp_config[i].tti.timer_ac_en =
1838                                 VXGE_HW_USE_FLASH_DEFAULT;
1839
1840                 device_config->vp_config[i].tti.timer_ci_en =
1841                                 VXGE_HW_USE_FLASH_DEFAULT;
1842
1843                 device_config->vp_config[i].tti.timer_ri_en =
1844                                 VXGE_HW_USE_FLASH_DEFAULT;
1845
1846                 device_config->vp_config[i].tti.rtimer_val =
1847                                 VXGE_HW_USE_FLASH_DEFAULT;
1848
1849                 device_config->vp_config[i].tti.util_sel =
1850                                 VXGE_HW_USE_FLASH_DEFAULT;
1851
1852                 device_config->vp_config[i].tti.ltimer_val =
1853                                 VXGE_HW_USE_FLASH_DEFAULT;
1854
1855                 device_config->vp_config[i].tti.urange_a =
1856                                 VXGE_HW_USE_FLASH_DEFAULT;
1857
1858                 device_config->vp_config[i].tti.uec_a =
1859                                 VXGE_HW_USE_FLASH_DEFAULT;
1860
1861                 device_config->vp_config[i].tti.urange_b =
1862                                 VXGE_HW_USE_FLASH_DEFAULT;
1863
1864                 device_config->vp_config[i].tti.uec_b =
1865                                 VXGE_HW_USE_FLASH_DEFAULT;
1866
1867                 device_config->vp_config[i].tti.urange_c =
1868                                 VXGE_HW_USE_FLASH_DEFAULT;
1869
1870                 device_config->vp_config[i].tti.uec_c =
1871                                 VXGE_HW_USE_FLASH_DEFAULT;
1872
1873                 device_config->vp_config[i].tti.uec_d =
1874                                 VXGE_HW_USE_FLASH_DEFAULT;
1875
1876                 device_config->vp_config[i].rti.intr_enable =
1877                                 VXGE_HW_TIM_INTR_DEFAULT;
1878
1879                 device_config->vp_config[i].rti.btimer_val =
1880                                 VXGE_HW_USE_FLASH_DEFAULT;
1881
1882                 device_config->vp_config[i].rti.timer_ac_en =
1883                                 VXGE_HW_USE_FLASH_DEFAULT;
1884
1885                 device_config->vp_config[i].rti.timer_ci_en =
1886                                 VXGE_HW_USE_FLASH_DEFAULT;
1887
1888                 device_config->vp_config[i].rti.timer_ri_en =
1889                                 VXGE_HW_USE_FLASH_DEFAULT;
1890
1891                 device_config->vp_config[i].rti.rtimer_val =
1892                                 VXGE_HW_USE_FLASH_DEFAULT;
1893
1894                 device_config->vp_config[i].rti.util_sel =
1895                                 VXGE_HW_USE_FLASH_DEFAULT;
1896
1897                 device_config->vp_config[i].rti.ltimer_val =
1898                                 VXGE_HW_USE_FLASH_DEFAULT;
1899
1900                 device_config->vp_config[i].rti.urange_a =
1901                                 VXGE_HW_USE_FLASH_DEFAULT;
1902
1903                 device_config->vp_config[i].rti.uec_a =
1904                                 VXGE_HW_USE_FLASH_DEFAULT;
1905
1906                 device_config->vp_config[i].rti.urange_b =
1907                                 VXGE_HW_USE_FLASH_DEFAULT;
1908
1909                 device_config->vp_config[i].rti.uec_b =
1910                                 VXGE_HW_USE_FLASH_DEFAULT;
1911
1912                 device_config->vp_config[i].rti.urange_c =
1913                                 VXGE_HW_USE_FLASH_DEFAULT;
1914
1915                 device_config->vp_config[i].rti.uec_c =
1916                                 VXGE_HW_USE_FLASH_DEFAULT;
1917
1918                 device_config->vp_config[i].rti.uec_d =
1919                                 VXGE_HW_USE_FLASH_DEFAULT;
1920
1921                 device_config->vp_config[i].mtu =
1922                                 VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU;
1923
1924                 device_config->vp_config[i].rpa_strip_vlan_tag =
1925                         VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT;
1926         }
1927
1928         return VXGE_HW_OK;
1929 }
1930
1931 /*
1932  * _hw_legacy_swapper_set - Set the swapper bits for the legacy secion.
1933  * Set the swapper bits appropriately for the lagacy section.
1934  */
1935 enum vxge_hw_status
1936 __vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg)
1937 {
1938         u64 val64;
1939         enum vxge_hw_status status = VXGE_HW_OK;
1940
1941         val64 = readq(&legacy_reg->toc_swapper_fb);
1942
1943         wmb();
1944
1945         switch (val64) {
1946
1947         case VXGE_HW_SWAPPER_INITIAL_VALUE:
1948                 return status;
1949
1950         case VXGE_HW_SWAPPER_BYTE_SWAPPED_BIT_FLIPPED:
1951                 writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE,
1952                         &legacy_reg->pifm_rd_swap_en);
1953                 writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE,
1954                         &legacy_reg->pifm_rd_flip_en);
1955                 writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE,
1956                         &legacy_reg->pifm_wr_swap_en);
1957                 writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE,
1958                         &legacy_reg->pifm_wr_flip_en);
1959                 break;
1960
1961         case VXGE_HW_SWAPPER_BYTE_SWAPPED:
1962                 writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE,
1963                         &legacy_reg->pifm_rd_swap_en);
1964                 writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE,
1965                         &legacy_reg->pifm_wr_swap_en);
1966                 break;
1967
1968         case VXGE_HW_SWAPPER_BIT_FLIPPED:
1969                 writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE,
1970                         &legacy_reg->pifm_rd_flip_en);
1971                 writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE,
1972                         &legacy_reg->pifm_wr_flip_en);
1973                 break;
1974         }
1975
1976         wmb();
1977
1978         val64 = readq(&legacy_reg->toc_swapper_fb);
1979
1980         if (val64 != VXGE_HW_SWAPPER_INITIAL_VALUE)
1981                 status = VXGE_HW_ERR_SWAPPER_CTRL;
1982
1983         return status;
1984 }
1985
1986 /*
1987  * __vxge_hw_vpath_swapper_set - Set the swapper bits for the vpath.
1988  * Set the swapper bits appropriately for the vpath.
1989  */
1990 enum vxge_hw_status
1991 __vxge_hw_vpath_swapper_set(struct vxge_hw_vpath_reg __iomem *vpath_reg)
1992 {
1993 #ifndef __BIG_ENDIAN
1994         u64 val64;
1995
1996         val64 = readq(&vpath_reg->vpath_general_cfg1);
1997         wmb();
1998         val64 |= VXGE_HW_VPATH_GENERAL_CFG1_CTL_BYTE_SWAPEN;
1999         writeq(val64, &vpath_reg->vpath_general_cfg1);
2000         wmb();
2001 #endif
2002         return VXGE_HW_OK;
2003 }
2004
2005 /*
2006  * __vxge_hw_kdfc_swapper_set - Set the swapper bits for the kdfc.
2007  * Set the swapper bits appropriately for the vpath.
2008  */
2009 enum vxge_hw_status
2010 __vxge_hw_kdfc_swapper_set(
2011         struct vxge_hw_legacy_reg __iomem *legacy_reg,
2012         struct vxge_hw_vpath_reg __iomem *vpath_reg)
2013 {
2014         u64 val64;
2015
2016         val64 = readq(&legacy_reg->pifm_wr_swap_en);
2017
2018         if (val64 == VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE) {
2019                 val64 = readq(&vpath_reg->kdfcctl_cfg0);
2020                 wmb();
2021
2022                 val64 |= VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO0 |
2023                         VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO1  |
2024                         VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO2;
2025
2026                 writeq(val64, &vpath_reg->kdfcctl_cfg0);
2027                 wmb();
2028         }
2029
2030         return VXGE_HW_OK;
2031 }
2032
2033 /*
2034  * vxge_hw_mgmt_device_config - Retrieve device configuration.
2035  * Get device configuration. Permits to retrieve at run-time configuration
2036  * values that were used to initialize and configure the device.
2037  */
2038 enum vxge_hw_status
2039 vxge_hw_mgmt_device_config(struct __vxge_hw_device *hldev,
2040                            struct vxge_hw_device_config *dev_config, int size)
2041 {
2042
2043         if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC))
2044                 return VXGE_HW_ERR_INVALID_DEVICE;
2045
2046         if (size != sizeof(struct vxge_hw_device_config))
2047                 return VXGE_HW_ERR_VERSION_CONFLICT;
2048
2049         memcpy(dev_config, &hldev->config,
2050                 sizeof(struct vxge_hw_device_config));
2051
2052         return VXGE_HW_OK;
2053 }
2054
2055 /*
2056  * vxge_hw_mgmt_reg_read - Read Titan register.
2057  */
2058 enum vxge_hw_status
2059 vxge_hw_mgmt_reg_read(struct __vxge_hw_device *hldev,
2060                       enum vxge_hw_mgmt_reg_type type,
2061                       u32 index, u32 offset, u64 *value)
2062 {
2063         enum vxge_hw_status status = VXGE_HW_OK;
2064
2065         if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
2066                 status = VXGE_HW_ERR_INVALID_DEVICE;
2067                 goto exit;
2068         }
2069
2070         switch (type) {
2071         case vxge_hw_mgmt_reg_type_legacy:
2072                 if (offset > sizeof(struct vxge_hw_legacy_reg) - 8) {
2073                         status = VXGE_HW_ERR_INVALID_OFFSET;
2074                         break;
2075                 }
2076                 *value = readq((void __iomem *)hldev->legacy_reg + offset);
2077                 break;
2078         case vxge_hw_mgmt_reg_type_toc:
2079                 if (offset > sizeof(struct vxge_hw_toc_reg) - 8) {
2080                         status = VXGE_HW_ERR_INVALID_OFFSET;
2081                         break;
2082                 }
2083                 *value = readq((void __iomem *)hldev->toc_reg + offset);
2084                 break;
2085         case vxge_hw_mgmt_reg_type_common:
2086                 if (offset > sizeof(struct vxge_hw_common_reg) - 8) {
2087                         status = VXGE_HW_ERR_INVALID_OFFSET;
2088                         break;
2089                 }
2090                 *value = readq((void __iomem *)hldev->common_reg + offset);
2091                 break;
2092         case vxge_hw_mgmt_reg_type_mrpcim:
2093                 if (!(hldev->access_rights &
2094                         VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) {
2095                         status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
2096                         break;
2097                 }
2098                 if (offset > sizeof(struct vxge_hw_mrpcim_reg) - 8) {
2099                         status = VXGE_HW_ERR_INVALID_OFFSET;
2100                         break;
2101                 }
2102                 *value = readq((void __iomem *)hldev->mrpcim_reg + offset);
2103                 break;
2104         case vxge_hw_mgmt_reg_type_srpcim:
2105                 if (!(hldev->access_rights &
2106                         VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM)) {
2107                         status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
2108                         break;
2109                 }
2110                 if (index > VXGE_HW_TITAN_SRPCIM_REG_SPACES - 1) {
2111                         status = VXGE_HW_ERR_INVALID_INDEX;
2112                         break;
2113                 }
2114                 if (offset > sizeof(struct vxge_hw_srpcim_reg) - 8) {
2115                         status = VXGE_HW_ERR_INVALID_OFFSET;
2116                         break;
2117                 }
2118                 *value = readq((void __iomem *)hldev->srpcim_reg[index] +
2119                                 offset);
2120                 break;
2121         case vxge_hw_mgmt_reg_type_vpmgmt:
2122                 if ((index > VXGE_HW_TITAN_VPMGMT_REG_SPACES - 1) ||
2123                         (!(hldev->vpath_assignments & vxge_mBIT(index)))) {
2124                         status = VXGE_HW_ERR_INVALID_INDEX;
2125                         break;
2126                 }
2127                 if (offset > sizeof(struct vxge_hw_vpmgmt_reg) - 8) {
2128                         status = VXGE_HW_ERR_INVALID_OFFSET;
2129                         break;
2130                 }
2131                 *value = readq((void __iomem *)hldev->vpmgmt_reg[index] +
2132                                 offset);
2133                 break;
2134         case vxge_hw_mgmt_reg_type_vpath:
2135                 if ((index > VXGE_HW_TITAN_VPATH_REG_SPACES - 1) ||
2136                         (!(hldev->vpath_assignments & vxge_mBIT(index)))) {
2137                         status = VXGE_HW_ERR_INVALID_INDEX;
2138                         break;
2139                 }
2140                 if (index > VXGE_HW_TITAN_VPATH_REG_SPACES - 1) {
2141                         status = VXGE_HW_ERR_INVALID_INDEX;
2142                         break;
2143                 }
2144                 if (offset > sizeof(struct vxge_hw_vpath_reg) - 8) {
2145                         status = VXGE_HW_ERR_INVALID_OFFSET;
2146                         break;
2147                 }
2148                 *value = readq((void __iomem *)hldev->vpath_reg[index] +
2149                                 offset);
2150                 break;
2151         default:
2152                 status = VXGE_HW_ERR_INVALID_TYPE;
2153                 break;
2154         }
2155
2156 exit:
2157         return status;
2158 }
2159
2160 /*
2161  * vxge_hw_vpath_strip_fcs_check - Check for FCS strip.
2162  */
2163 enum vxge_hw_status
2164 vxge_hw_vpath_strip_fcs_check(struct __vxge_hw_device *hldev, u64 vpath_mask)
2165 {
2166         struct vxge_hw_vpmgmt_reg       __iomem *vpmgmt_reg;
2167         enum vxge_hw_status status = VXGE_HW_OK;
2168         int i = 0, j = 0;
2169
2170         for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
2171                 if (!((vpath_mask) & vxge_mBIT(i)))
2172                         continue;
2173                 vpmgmt_reg = hldev->vpmgmt_reg[i];
2174                 for (j = 0; j < VXGE_HW_MAC_MAX_MAC_PORT_ID; j++) {
2175                         if (readq(&vpmgmt_reg->rxmac_cfg0_port_vpmgmt_clone[j])
2176                         & VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_STRIP_FCS)
2177                                 return VXGE_HW_FAIL;
2178                 }
2179         }
2180         return status;
2181 }
2182 /*
2183  * vxge_hw_mgmt_reg_Write - Write Titan register.
2184  */
2185 enum vxge_hw_status
2186 vxge_hw_mgmt_reg_write(struct __vxge_hw_device *hldev,
2187                       enum vxge_hw_mgmt_reg_type type,
2188                       u32 index, u32 offset, u64 value)
2189 {
2190         enum vxge_hw_status status = VXGE_HW_OK;
2191
2192         if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
2193                 status = VXGE_HW_ERR_INVALID_DEVICE;
2194                 goto exit;
2195         }
2196
2197         switch (type) {
2198         case vxge_hw_mgmt_reg_type_legacy:
2199                 if (offset > sizeof(struct vxge_hw_legacy_reg) - 8) {
2200                         status = VXGE_HW_ERR_INVALID_OFFSET;
2201                         break;
2202                 }
2203                 writeq(value, (void __iomem *)hldev->legacy_reg + offset);
2204                 break;
2205         case vxge_hw_mgmt_reg_type_toc:
2206                 if (offset > sizeof(struct vxge_hw_toc_reg) - 8) {
2207                         status = VXGE_HW_ERR_INVALID_OFFSET;
2208                         break;
2209                 }
2210                 writeq(value, (void __iomem *)hldev->toc_reg + offset);
2211                 break;
2212         case vxge_hw_mgmt_reg_type_common:
2213                 if (offset > sizeof(struct vxge_hw_common_reg) - 8) {
2214                         status = VXGE_HW_ERR_INVALID_OFFSET;
2215                         break;
2216                 }
2217                 writeq(value, (void __iomem *)hldev->common_reg + offset);
2218                 break;
2219         case vxge_hw_mgmt_reg_type_mrpcim:
2220                 if (!(hldev->access_rights &
2221                         VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) {
2222                         status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
2223                         break;
2224                 }
2225                 if (offset > sizeof(struct vxge_hw_mrpcim_reg) - 8) {
2226                         status = VXGE_HW_ERR_INVALID_OFFSET;
2227                         break;
2228                 }
2229                 writeq(value, (void __iomem *)hldev->mrpcim_reg + offset);
2230                 break;
2231         case vxge_hw_mgmt_reg_type_srpcim:
2232                 if (!(hldev->access_rights &
2233                         VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM)) {
2234                         status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
2235                         break;
2236                 }
2237                 if (index > VXGE_HW_TITAN_SRPCIM_REG_SPACES - 1) {
2238                         status = VXGE_HW_ERR_INVALID_INDEX;
2239                         break;
2240                 }
2241                 if (offset > sizeof(struct vxge_hw_srpcim_reg) - 8) {
2242                         status = VXGE_HW_ERR_INVALID_OFFSET;
2243                         break;
2244                 }
2245                 writeq(value, (void __iomem *)hldev->srpcim_reg[index] +
2246                         offset);
2247
2248                 break;
2249         case vxge_hw_mgmt_reg_type_vpmgmt:
2250                 if ((index > VXGE_HW_TITAN_VPMGMT_REG_SPACES - 1) ||
2251                         (!(hldev->vpath_assignments & vxge_mBIT(index)))) {
2252                         status = VXGE_HW_ERR_INVALID_INDEX;
2253                         break;
2254                 }
2255                 if (offset > sizeof(struct vxge_hw_vpmgmt_reg) - 8) {
2256                         status = VXGE_HW_ERR_INVALID_OFFSET;
2257                         break;
2258                 }
2259                 writeq(value, (void __iomem *)hldev->vpmgmt_reg[index] +
2260                         offset);
2261                 break;
2262         case vxge_hw_mgmt_reg_type_vpath:
2263                 if ((index > VXGE_HW_TITAN_VPATH_REG_SPACES-1) ||
2264                         (!(hldev->vpath_assignments & vxge_mBIT(index)))) {
2265                         status = VXGE_HW_ERR_INVALID_INDEX;
2266                         break;
2267                 }
2268                 if (offset > sizeof(struct vxge_hw_vpath_reg) - 8) {
2269                         status = VXGE_HW_ERR_INVALID_OFFSET;
2270                         break;
2271                 }
2272                 writeq(value, (void __iomem *)hldev->vpath_reg[index] +
2273                         offset);
2274                 break;
2275         default:
2276                 status = VXGE_HW_ERR_INVALID_TYPE;
2277                 break;
2278         }
2279 exit:
2280         return status;
2281 }
2282
2283 /*
2284  * __vxge_hw_fifo_mempool_item_alloc - Allocate List blocks for TxD
2285  * list callback
2286  * This function is callback passed to __vxge_hw_mempool_create to create memory
2287  * pool for TxD list
2288  */
2289 static void
2290 __vxge_hw_fifo_mempool_item_alloc(
2291         struct vxge_hw_mempool *mempoolh,
2292         u32 memblock_index, struct vxge_hw_mempool_dma *dma_object,
2293         u32 index, u32 is_last)
2294 {
2295         u32 memblock_item_idx;
2296         struct __vxge_hw_fifo_txdl_priv *txdl_priv;
2297         struct vxge_hw_fifo_txd *txdp =
2298                 (struct vxge_hw_fifo_txd *)mempoolh->items_arr[index];
2299         struct __vxge_hw_fifo *fifo =
2300                         (struct __vxge_hw_fifo *)mempoolh->userdata;
2301         void *memblock = mempoolh->memblocks_arr[memblock_index];
2302
2303         vxge_assert(txdp);
2304
2305         txdp->host_control = (u64) (size_t)
2306         __vxge_hw_mempool_item_priv(mempoolh, memblock_index, txdp,
2307                                         &memblock_item_idx);
2308
2309         txdl_priv = __vxge_hw_fifo_txdl_priv(fifo, txdp);
2310
2311         vxge_assert(txdl_priv);
2312
2313         fifo->channel.reserve_arr[fifo->channel.reserve_ptr - 1 - index] = txdp;
2314
2315         /* pre-format HW's TxDL's private */
2316         txdl_priv->dma_offset = (char *)txdp - (char *)memblock;
2317         txdl_priv->dma_addr = dma_object->addr + txdl_priv->dma_offset;
2318         txdl_priv->dma_handle = dma_object->handle;
2319         txdl_priv->memblock   = memblock;
2320         txdl_priv->first_txdp = txdp;
2321         txdl_priv->next_txdl_priv = NULL;
2322         txdl_priv->alloc_frags = 0;
2323
2324         return;
2325 }
2326
2327 /*
2328  * __vxge_hw_fifo_create - Create a FIFO
2329  * This function creates FIFO and initializes it.
2330  */
2331 enum vxge_hw_status
2332 __vxge_hw_fifo_create(struct __vxge_hw_vpath_handle *vp,
2333                       struct vxge_hw_fifo_attr *attr)
2334 {
2335         enum vxge_hw_status status = VXGE_HW_OK;
2336         struct __vxge_hw_fifo *fifo;
2337         struct vxge_hw_fifo_config *config;
2338         u32 txdl_size, txdl_per_memblock;
2339         struct vxge_hw_mempool_cbs fifo_mp_callback;
2340         struct __vxge_hw_virtualpath *vpath;
2341
2342         if ((vp == NULL) || (attr == NULL)) {
2343                 status = VXGE_HW_ERR_INVALID_HANDLE;
2344                 goto exit;
2345         }
2346         vpath = vp->vpath;
2347         config = &vpath->hldev->config.vp_config[vpath->vp_id].fifo;
2348
2349         txdl_size = config->max_frags * sizeof(struct vxge_hw_fifo_txd);
2350
2351         txdl_per_memblock = config->memblock_size / txdl_size;
2352
2353         fifo = (struct __vxge_hw_fifo *)__vxge_hw_channel_allocate(vp,
2354                                         VXGE_HW_CHANNEL_TYPE_FIFO,
2355                                         config->fifo_blocks * txdl_per_memblock,
2356                                         attr->per_txdl_space, attr->userdata);
2357
2358         if (fifo == NULL) {
2359                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
2360                 goto exit;
2361         }
2362
2363         vpath->fifoh = fifo;
2364         fifo->nofl_db = vpath->nofl_db;
2365
2366         fifo->vp_id = vpath->vp_id;
2367         fifo->vp_reg = vpath->vp_reg;
2368         fifo->stats = &vpath->sw_stats->fifo_stats;
2369
2370         fifo->config = config;
2371
2372         /* apply "interrupts per txdl" attribute */
2373         fifo->interrupt_type = VXGE_HW_FIFO_TXD_INT_TYPE_UTILZ;
2374
2375         if (fifo->config->intr)
2376                 fifo->interrupt_type = VXGE_HW_FIFO_TXD_INT_TYPE_PER_LIST;
2377
2378         fifo->no_snoop_bits = config->no_snoop_bits;
2379
2380         /*
2381          * FIFO memory management strategy:
2382          *
2383          * TxDL split into three independent parts:
2384          *      - set of TxD's
2385          *      - TxD HW private part
2386          *      - driver private part
2387          *
2388          * Adaptative memory allocation used. i.e. Memory allocated on
2389          * demand with the size which will fit into one memory block.
2390          * One memory block may contain more than one TxDL.
2391          *
2392          * During "reserve" operations more memory can be allocated on demand
2393          * for example due to FIFO full condition.
2394          *
2395          * Pool of memory memblocks never shrinks except in __vxge_hw_fifo_close
2396          * routine which will essentially stop the channel and free resources.
2397          */
2398
2399         /* TxDL common private size == TxDL private  +  driver private */
2400         fifo->priv_size =
2401                 sizeof(struct __vxge_hw_fifo_txdl_priv) + attr->per_txdl_space;
2402         fifo->priv_size = ((fifo->priv_size  +  VXGE_CACHE_LINE_SIZE - 1) /
2403                         VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE;
2404
2405         fifo->per_txdl_space = attr->per_txdl_space;
2406
2407         /* recompute txdl size to be cacheline aligned */
2408         fifo->txdl_size = txdl_size;
2409         fifo->txdl_per_memblock = txdl_per_memblock;
2410
2411         fifo->txdl_term = attr->txdl_term;
2412         fifo->callback = attr->callback;
2413
2414         if (fifo->txdl_per_memblock == 0) {
2415                 __vxge_hw_fifo_delete(vp);
2416                 status = VXGE_HW_ERR_INVALID_BLOCK_SIZE;
2417                 goto exit;
2418         }
2419
2420         fifo_mp_callback.item_func_alloc = __vxge_hw_fifo_mempool_item_alloc;
2421
2422         fifo->mempool =
2423                 __vxge_hw_mempool_create(vpath->hldev,
2424                         fifo->config->memblock_size,
2425                         fifo->txdl_size,
2426                         fifo->priv_size,
2427                         (fifo->config->fifo_blocks * fifo->txdl_per_memblock),
2428                         (fifo->config->fifo_blocks * fifo->txdl_per_memblock),
2429                         &fifo_mp_callback,
2430                         fifo);
2431
2432         if (fifo->mempool == NULL) {
2433                 __vxge_hw_fifo_delete(vp);
2434                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
2435                 goto exit;
2436         }
2437
2438         status = __vxge_hw_channel_initialize(&fifo->channel);
2439         if (status != VXGE_HW_OK) {
2440                 __vxge_hw_fifo_delete(vp);
2441                 goto exit;
2442         }
2443
2444         vxge_assert(fifo->channel.reserve_ptr);
2445 exit:
2446         return status;
2447 }
2448
2449 /*
2450  * __vxge_hw_fifo_abort - Returns the TxD
2451  * This function terminates the TxDs of fifo
2452  */
2453 enum vxge_hw_status __vxge_hw_fifo_abort(struct __vxge_hw_fifo *fifo)
2454 {
2455         void *txdlh;
2456
2457         for (;;) {
2458                 vxge_hw_channel_dtr_try_complete(&fifo->channel, &txdlh);
2459
2460                 if (txdlh == NULL)
2461                         break;
2462
2463                 vxge_hw_channel_dtr_complete(&fifo->channel);
2464
2465                 if (fifo->txdl_term) {
2466                         fifo->txdl_term(txdlh,
2467                         VXGE_HW_TXDL_STATE_POSTED,
2468                         fifo->channel.userdata);
2469                 }
2470
2471                 vxge_hw_channel_dtr_free(&fifo->channel, txdlh);
2472         }
2473
2474         return VXGE_HW_OK;
2475 }
2476
2477 /*
2478  * __vxge_hw_fifo_reset - Resets the fifo
2479  * This function resets the fifo during vpath reset operation
2480  */
2481 enum vxge_hw_status __vxge_hw_fifo_reset(struct __vxge_hw_fifo *fifo)
2482 {
2483         enum vxge_hw_status status = VXGE_HW_OK;
2484
2485         __vxge_hw_fifo_abort(fifo);
2486         status = __vxge_hw_channel_reset(&fifo->channel);
2487
2488         return status;
2489 }
2490
2491 /*
2492  * __vxge_hw_fifo_delete - Removes the FIFO
2493  * This function freeup the memory pool and removes the FIFO
2494  */
2495 enum vxge_hw_status __vxge_hw_fifo_delete(struct __vxge_hw_vpath_handle *vp)
2496 {
2497         struct __vxge_hw_fifo *fifo = vp->vpath->fifoh;
2498
2499         __vxge_hw_fifo_abort(fifo);
2500
2501         if (fifo->mempool)
2502                 __vxge_hw_mempool_destroy(fifo->mempool);
2503
2504         vp->vpath->fifoh = NULL;
2505
2506         __vxge_hw_channel_free(&fifo->channel);
2507
2508         return VXGE_HW_OK;
2509 }
2510
2511 /*
2512  * __vxge_hw_vpath_pci_read - Read the content of given address
2513  *                          in pci config space.
2514  * Read from the vpath pci config space.
2515  */
2516 enum vxge_hw_status
2517 __vxge_hw_vpath_pci_read(struct __vxge_hw_virtualpath *vpath,
2518                          u32 phy_func_0, u32 offset, u32 *val)
2519 {
2520         u64 val64;
2521         enum vxge_hw_status status = VXGE_HW_OK;
2522         struct vxge_hw_vpath_reg __iomem *vp_reg = vpath->vp_reg;
2523
2524         val64 = VXGE_HW_PCI_CONFIG_ACCESS_CFG1_ADDRESS(offset);
2525
2526         if (phy_func_0)
2527                 val64 |= VXGE_HW_PCI_CONFIG_ACCESS_CFG1_SEL_FUNC0;
2528
2529         writeq(val64, &vp_reg->pci_config_access_cfg1);
2530         wmb();
2531         writeq(VXGE_HW_PCI_CONFIG_ACCESS_CFG2_REQ,
2532                         &vp_reg->pci_config_access_cfg2);
2533         wmb();
2534
2535         status = __vxge_hw_device_register_poll(
2536                         &vp_reg->pci_config_access_cfg2,
2537                         VXGE_HW_INTR_MASK_ALL, VXGE_HW_DEF_DEVICE_POLL_MILLIS);
2538
2539         if (status != VXGE_HW_OK)
2540                 goto exit;
2541
2542         val64 = readq(&vp_reg->pci_config_access_status);
2543
2544         if (val64 & VXGE_HW_PCI_CONFIG_ACCESS_STATUS_ACCESS_ERR) {
2545                 status = VXGE_HW_FAIL;
2546                 *val = 0;
2547         } else
2548                 *val = (u32)vxge_bVALn(val64, 32, 32);
2549 exit:
2550         return status;
2551 }
2552
2553 /*
2554  * __vxge_hw_vpath_func_id_get - Get the function id of the vpath.
2555  * Returns the function number of the vpath.
2556  */
2557 u32
2558 __vxge_hw_vpath_func_id_get(u32 vp_id,
2559         struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg)
2560 {
2561         u64 val64;
2562
2563         val64 = readq(&vpmgmt_reg->vpath_to_func_map_cfg1);
2564
2565         return
2566          (u32)VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_GET_VPATH_TO_FUNC_MAP_CFG1(val64);
2567 }
2568
2569 /*
2570  * __vxge_hw_read_rts_ds - Program RTS steering critieria
2571  */
2572 static inline void
2573 __vxge_hw_read_rts_ds(struct vxge_hw_vpath_reg __iomem *vpath_reg,
2574                       u64 dta_struct_sel)
2575 {
2576         writeq(0, &vpath_reg->rts_access_steer_ctrl);
2577         wmb();
2578         writeq(dta_struct_sel, &vpath_reg->rts_access_steer_data0);
2579         writeq(0, &vpath_reg->rts_access_steer_data1);
2580         wmb();
2581         return;
2582 }
2583
2584
2585 /*
2586  * __vxge_hw_vpath_card_info_get - Get the serial numbers,
2587  * part number and product description.
2588  */
2589 enum vxge_hw_status
2590 __vxge_hw_vpath_card_info_get(
2591         u32 vp_id,
2592         struct vxge_hw_vpath_reg __iomem *vpath_reg,
2593         struct vxge_hw_device_hw_info *hw_info)
2594 {
2595         u32 i, j;
2596         u64 val64;
2597         u64 data1 = 0ULL;
2598         u64 data2 = 0ULL;
2599         enum vxge_hw_status status = VXGE_HW_OK;
2600         u8 *serial_number = hw_info->serial_number;
2601         u8 *part_number = hw_info->part_number;
2602         u8 *product_desc = hw_info->product_desc;
2603
2604         __vxge_hw_read_rts_ds(vpath_reg,
2605                 VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_SERIAL_NUMBER);
2606
2607         val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
2608                         VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
2609                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
2610                         VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
2611                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
2612                 VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
2613
2614         status = __vxge_hw_pio_mem_write64(val64,
2615                                 &vpath_reg->rts_access_steer_ctrl,
2616                                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
2617                                 VXGE_HW_DEF_DEVICE_POLL_MILLIS);
2618
2619         if (status != VXGE_HW_OK)
2620                 return status;
2621
2622         val64 = readq(&vpath_reg->rts_access_steer_ctrl);
2623
2624         if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
2625                 data1 = readq(&vpath_reg->rts_access_steer_data0);
2626                 ((u64 *)serial_number)[0] = be64_to_cpu(data1);
2627
2628                 data2 = readq(&vpath_reg->rts_access_steer_data1);
2629                 ((u64 *)serial_number)[1] = be64_to_cpu(data2);
2630                 status = VXGE_HW_OK;
2631         } else
2632                 *serial_number = 0;
2633
2634         __vxge_hw_read_rts_ds(vpath_reg,
2635                         VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PART_NUMBER);
2636
2637         val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
2638                         VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
2639                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
2640                         VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
2641                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
2642                 VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
2643
2644         status = __vxge_hw_pio_mem_write64(val64,
2645                                 &vpath_reg->rts_access_steer_ctrl,
2646                                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
2647                                 VXGE_HW_DEF_DEVICE_POLL_MILLIS);
2648
2649         if (status != VXGE_HW_OK)
2650                 return status;
2651
2652         val64 = readq(&vpath_reg->rts_access_steer_ctrl);
2653
2654         if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
2655
2656                 data1 = readq(&vpath_reg->rts_access_steer_data0);
2657                 ((u64 *)part_number)[0] = be64_to_cpu(data1);
2658
2659                 data2 = readq(&vpath_reg->rts_access_steer_data1);
2660                 ((u64 *)part_number)[1] = be64_to_cpu(data2);
2661
2662                 status = VXGE_HW_OK;
2663
2664         } else
2665                 *part_number = 0;
2666
2667         j = 0;
2668
2669         for (i = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_0;
2670              i <= VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_3; i++) {
2671
2672                 __vxge_hw_read_rts_ds(vpath_reg, i);
2673
2674                 val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
2675                         VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
2676                         VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
2677                         VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
2678                         VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
2679                         VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
2680
2681                 status = __vxge_hw_pio_mem_write64(val64,
2682                                 &vpath_reg->rts_access_steer_ctrl,
2683                                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
2684                                 VXGE_HW_DEF_DEVICE_POLL_MILLIS);
2685
2686                 if (status != VXGE_HW_OK)
2687                         return status;
2688
2689                 val64 = readq(&vpath_reg->rts_access_steer_ctrl);
2690
2691                 if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
2692
2693                         data1 = readq(&vpath_reg->rts_access_steer_data0);
2694                         ((u64 *)product_desc)[j++] = be64_to_cpu(data1);
2695
2696                         data2 = readq(&vpath_reg->rts_access_steer_data1);
2697                         ((u64 *)product_desc)[j++] = be64_to_cpu(data2);
2698
2699                         status = VXGE_HW_OK;
2700                 } else
2701                         *product_desc = 0;
2702         }
2703
2704         return status;
2705 }
2706
2707 /*
2708  * __vxge_hw_vpath_fw_ver_get - Get the fw version
2709  * Returns FW Version
2710  */
2711 enum vxge_hw_status
2712 __vxge_hw_vpath_fw_ver_get(
2713         u32 vp_id,
2714         struct vxge_hw_vpath_reg __iomem *vpath_reg,
2715         struct vxge_hw_device_hw_info *hw_info)
2716 {
2717         u64 val64;
2718         u64 data1 = 0ULL;
2719         u64 data2 = 0ULL;
2720         struct vxge_hw_device_version *fw_version = &hw_info->fw_version;
2721         struct vxge_hw_device_date *fw_date = &hw_info->fw_date;
2722         struct vxge_hw_device_version *flash_version = &hw_info->flash_version;
2723         struct vxge_hw_device_date *flash_date = &hw_info->flash_date;
2724         enum vxge_hw_status status = VXGE_HW_OK;
2725
2726         val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
2727                 VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY) |
2728                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
2729                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
2730                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
2731                 VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
2732
2733         status = __vxge_hw_pio_mem_write64(val64,
2734                                 &vpath_reg->rts_access_steer_ctrl,
2735                                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
2736                                 VXGE_HW_DEF_DEVICE_POLL_MILLIS);
2737
2738         if (status != VXGE_HW_OK)
2739                 goto exit;
2740
2741         val64 = readq(&vpath_reg->rts_access_steer_ctrl);
2742
2743         if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
2744
2745                 data1 = readq(&vpath_reg->rts_access_steer_data0);
2746                 data2 = readq(&vpath_reg->rts_access_steer_data1);
2747
2748                 fw_date->day =
2749                         (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_DAY(
2750                                                 data1);
2751                 fw_date->month =
2752                         (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MONTH(
2753                                                 data1);
2754                 fw_date->year =
2755                         (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_YEAR(
2756                                                 data1);
2757
2758                 snprintf(fw_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d",
2759                         fw_date->month, fw_date->day, fw_date->year);
2760
2761                 fw_version->major =
2762                     (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data1);
2763                 fw_version->minor =
2764                     (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data1);
2765                 fw_version->build =
2766                     (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data1);
2767
2768                 snprintf(fw_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d",
2769                     fw_version->major, fw_version->minor, fw_version->build);
2770
2771                 flash_date->day =
2772                   (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_DAY(data2);
2773                 flash_date->month =
2774                  (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MONTH(data2);
2775                 flash_date->year =
2776                  (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_YEAR(data2);
2777
2778                 snprintf(flash_date->date, VXGE_HW_FW_STRLEN,
2779                         "%2.2d/%2.2d/%4.4d",
2780                         flash_date->month, flash_date->day, flash_date->year);
2781
2782                 flash_version->major =
2783                  (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MAJOR(data2);
2784                 flash_version->minor =
2785                  (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MINOR(data2);
2786                 flash_version->build =
2787                  (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(data2);
2788
2789                 snprintf(flash_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d",
2790                         flash_version->major, flash_version->minor,
2791                         flash_version->build);
2792
2793                 status = VXGE_HW_OK;
2794
2795         } else
2796                 status = VXGE_HW_FAIL;
2797 exit:
2798         return status;
2799 }
2800
2801 /*
2802  * __vxge_hw_vpath_pci_func_mode_get - Get the pci mode
2803  * Returns pci function mode
2804  */
2805 u64
2806 __vxge_hw_vpath_pci_func_mode_get(
2807         u32  vp_id,
2808         struct vxge_hw_vpath_reg __iomem *vpath_reg)
2809 {
2810         u64 val64;
2811         u64 data1 = 0ULL;
2812         enum vxge_hw_status status = VXGE_HW_OK;
2813
2814         __vxge_hw_read_rts_ds(vpath_reg,
2815                 VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PCI_MODE);
2816
2817         val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
2818                         VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
2819                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
2820                         VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
2821                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
2822                 VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
2823
2824         status = __vxge_hw_pio_mem_write64(val64,
2825                                 &vpath_reg->rts_access_steer_ctrl,
2826                                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
2827                                 VXGE_HW_DEF_DEVICE_POLL_MILLIS);
2828
2829         if (status != VXGE_HW_OK)
2830                 goto exit;
2831
2832         val64 = readq(&vpath_reg->rts_access_steer_ctrl);
2833
2834         if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
2835                 data1 = readq(&vpath_reg->rts_access_steer_data0);
2836                 status = VXGE_HW_OK;
2837         } else {
2838                 data1 = 0;
2839                 status = VXGE_HW_FAIL;
2840         }
2841 exit:
2842         return data1;
2843 }
2844
2845 /**
2846  * vxge_hw_device_flick_link_led - Flick (blink) link LED.
2847  * @hldev: HW device.
2848  * @on_off: TRUE if flickering to be on, FALSE to be off
2849  *
2850  * Flicker the link LED.
2851  */
2852 enum vxge_hw_status
2853 vxge_hw_device_flick_link_led(struct __vxge_hw_device *hldev,
2854                                u64 on_off)
2855 {
2856         u64 val64;
2857         enum vxge_hw_status status = VXGE_HW_OK;
2858         struct vxge_hw_vpath_reg __iomem *vp_reg;
2859
2860         if (hldev == NULL) {
2861                 status = VXGE_HW_ERR_INVALID_DEVICE;
2862                 goto exit;
2863         }
2864
2865         vp_reg = hldev->vpath_reg[hldev->first_vp_id];
2866
2867         writeq(0, &vp_reg->rts_access_steer_ctrl);
2868         wmb();
2869         writeq(on_off, &vp_reg->rts_access_steer_data0);
2870         writeq(0, &vp_reg->rts_access_steer_data1);
2871         wmb();
2872
2873         val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
2874                         VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LED_CONTROL) |
2875                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
2876                         VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
2877                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
2878                 VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
2879
2880         status = __vxge_hw_pio_mem_write64(val64,
2881                                 &vp_reg->rts_access_steer_ctrl,
2882                                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
2883                                 VXGE_HW_DEF_DEVICE_POLL_MILLIS);
2884 exit:
2885         return status;
2886 }
2887
2888 /*
2889  * __vxge_hw_vpath_rts_table_get - Get the entries from RTS access tables
2890  */
2891 enum vxge_hw_status
2892 __vxge_hw_vpath_rts_table_get(
2893         struct __vxge_hw_vpath_handle *vp,
2894         u32 action, u32 rts_table, u32 offset, u64 *data1, u64 *data2)
2895 {
2896         u64 val64;
2897         struct __vxge_hw_virtualpath *vpath;
2898         struct vxge_hw_vpath_reg __iomem *vp_reg;
2899
2900         enum vxge_hw_status status = VXGE_HW_OK;
2901
2902         if (vp == NULL) {
2903                 status = VXGE_HW_ERR_INVALID_HANDLE;
2904                 goto exit;
2905         }
2906
2907         vpath = vp->vpath;
2908         vp_reg = vpath->vp_reg;
2909
2910         val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) |
2911                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(rts_table) |
2912                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
2913                 VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset);
2914
2915         if ((rts_table ==
2916                 VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT) ||
2917             (rts_table ==
2918                 VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT) ||
2919             (rts_table ==
2920                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK) ||
2921             (rts_table ==
2922                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY)) {
2923                 val64 = val64 | VXGE_HW_RTS_ACCESS_STEER_CTRL_TABLE_SEL;
2924         }
2925
2926         status = __vxge_hw_pio_mem_write64(val64,
2927                                 &vp_reg->rts_access_steer_ctrl,
2928                                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
2929                                 vpath->hldev->config.device_poll_millis);
2930
2931         if (status != VXGE_HW_OK)
2932                 goto exit;
2933
2934         val64 = readq(&vp_reg->rts_access_steer_ctrl);
2935
2936         if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
2937
2938                 *data1 = readq(&vp_reg->rts_access_steer_data0);
2939
2940                 if ((rts_table ==
2941                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) ||
2942                 (rts_table ==
2943                 VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) {
2944                         *data2 = readq(&vp_reg->rts_access_steer_data1);
2945                 }
2946                 status = VXGE_HW_OK;
2947         } else
2948                 status = VXGE_HW_FAIL;
2949 exit:
2950         return status;
2951 }
2952
2953 /*
2954  * __vxge_hw_vpath_rts_table_set - Set the entries of RTS access tables
2955  */
2956 enum vxge_hw_status
2957 __vxge_hw_vpath_rts_table_set(
2958         struct __vxge_hw_vpath_handle *vp, u32 action, u32 rts_table,
2959         u32 offset, u64 data1, u64 data2)
2960 {
2961         u64 val64;
2962         struct __vxge_hw_virtualpath *vpath;
2963         enum vxge_hw_status status = VXGE_HW_OK;
2964         struct vxge_hw_vpath_reg __iomem *vp_reg;
2965
2966         if (vp == NULL) {
2967                 status = VXGE_HW_ERR_INVALID_HANDLE;
2968                 goto exit;
2969         }
2970
2971         vpath = vp->vpath;
2972         vp_reg = vpath->vp_reg;
2973
2974         writeq(data1, &vp_reg->rts_access_steer_data0);
2975         wmb();
2976
2977         if ((rts_table == VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) ||
2978             (rts_table ==
2979                 VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) {
2980                 writeq(data2, &vp_reg->rts_access_steer_data1);
2981                 wmb();
2982         }
2983
2984         val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) |
2985                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(rts_table) |
2986                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
2987                 VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset);
2988
2989         status = __vxge_hw_pio_mem_write64(val64,
2990                                 &vp_reg->rts_access_steer_ctrl,
2991                                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
2992                                 vpath->hldev->config.device_poll_millis);
2993
2994         if (status != VXGE_HW_OK)
2995                 goto exit;
2996
2997         val64 = readq(&vp_reg->rts_access_steer_ctrl);
2998
2999         if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS)
3000                 status = VXGE_HW_OK;
3001         else
3002                 status = VXGE_HW_FAIL;
3003 exit:
3004         return status;
3005 }
3006
3007 /*
3008  * __vxge_hw_vpath_addr_get - Get the hw address entry for this vpath
3009  *               from MAC address table.
3010  */
3011 enum vxge_hw_status
3012 __vxge_hw_vpath_addr_get(
3013         u32 vp_id, struct vxge_hw_vpath_reg __iomem *vpath_reg,
3014         u8 (macaddr)[ETH_ALEN], u8 (macaddr_mask)[ETH_ALEN])
3015 {
3016         u32 i;
3017         u64 val64;
3018         u64 data1 = 0ULL;
3019         u64 data2 = 0ULL;
3020         enum vxge_hw_status status = VXGE_HW_OK;
3021
3022         val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
3023                 VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY) |
3024                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
3025                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) |
3026                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
3027                 VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
3028
3029         status = __vxge_hw_pio_mem_write64(val64,
3030                                 &vpath_reg->rts_access_steer_ctrl,
3031                                 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
3032                                 VXGE_HW_DEF_DEVICE_POLL_MILLIS);
3033
3034         if (status != VXGE_HW_OK)
3035                 goto exit;
3036
3037         val64 = readq(&vpath_reg->rts_access_steer_ctrl);
3038
3039         if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
3040
3041                 data1 = readq(&vpath_reg->rts_access_steer_data0);
3042                 data2 = readq(&vpath_reg->rts_access_steer_data1);
3043
3044                 data1 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data1);
3045                 data2 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK(
3046                                                         data2);
3047
3048                 for (i = ETH_ALEN; i > 0; i--) {
3049                         macaddr[i-1] = (u8)(data1 & 0xFF);
3050                         data1 >>= 8;
3051
3052                         macaddr_mask[i-1] = (u8)(data2 & 0xFF);
3053                         data2 >>= 8;
3054                 }
3055                 status = VXGE_HW_OK;
3056         } else
3057                 status = VXGE_HW_FAIL;
3058 exit:
3059         return status;
3060 }
3061
3062 /*
3063  * vxge_hw_vpath_rts_rth_set - Set/configure RTS hashing.
3064  */
3065 enum vxge_hw_status vxge_hw_vpath_rts_rth_set(
3066                         struct __vxge_hw_vpath_handle *vp,
3067                         enum vxge_hw_rth_algoritms algorithm,
3068                         struct vxge_hw_rth_hash_types *hash_type,
3069                         u16 bucket_size)
3070 {
3071         u64 data0, data1;
3072         enum vxge_hw_status status = VXGE_HW_OK;
3073
3074         if (vp == NULL) {
3075                 status = VXGE_HW_ERR_INVALID_HANDLE;
3076                 goto exit;
3077         }
3078
3079         status = __vxge_hw_vpath_rts_table_get(vp,
3080                      VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY,
3081                      VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG,
3082                         0, &data0, &data1);
3083
3084         data0 &= ~(VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(0xf) |
3085                         VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(0x3));
3086
3087         data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_EN |
3088         VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(bucket_size) |
3089         VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(algorithm);
3090
3091         if (hash_type->hash_type_tcpipv4_en)
3092                 data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV4_EN;
3093
3094         if (hash_type->hash_type_ipv4_en)
3095                 data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV4_EN;
3096
3097         if (hash_type->hash_type_tcpipv6_en)
3098                 data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV6_EN;
3099
3100         if (hash_type->hash_type_ipv6_en)
3101                 data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV6_EN;
3102
3103         if (hash_type->hash_type_tcpipv6ex_en)
3104                 data0 |=
3105                 VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV6_EX_EN;
3106
3107         if (hash_type->hash_type_ipv6ex_en)
3108                 data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV6_EX_EN;
3109
3110         if (VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_ACTIVE_TABLE(data0))
3111                 data0 &= ~VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ACTIVE_TABLE;
3112         else
3113                 data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ACTIVE_TABLE;
3114
3115         status = __vxge_hw_vpath_rts_table_set(vp,
3116                 VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY,
3117                 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG,
3118                 0, data0, 0);
3119 exit:
3120         return status;
3121 }
3122
3123 static void
3124 vxge_hw_rts_rth_data0_data1_get(u32 j, u64 *data0, u64 *data1,
3125                                 u16 flag, u8 *itable)
3126 {
3127         switch (flag) {
3128         case 1:
3129                 *data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_BUCKET_NUM(j)|
3130                         VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_ENTRY_EN |
3131                         VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_BUCKET_DATA(
3132                         itable[j]);
3133         case 2:
3134                 *data0 |=
3135                         VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_BUCKET_NUM(j)|
3136                         VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_ENTRY_EN |
3137                         VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_BUCKET_DATA(
3138                         itable[j]);
3139         case 3:
3140                 *data1 = VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_BUCKET_NUM(j)|
3141                         VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_ENTRY_EN |
3142                         VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_BUCKET_DATA(
3143                         itable[j]);
3144         case 4:
3145                 *data1 |=
3146                         VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_BUCKET_NUM(j)|
3147                         VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_ENTRY_EN |
3148                         VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_BUCKET_DATA(
3149                         itable[j]);
3150         default:
3151                 return;
3152         }
3153 }
3154 /*
3155  * vxge_hw_vpath_rts_rth_itable_set - Set/configure indirection table (IT).
3156  */
3157 enum vxge_hw_status vxge_hw_vpath_rts_rth_itable_set(
3158                         struct __vxge_hw_vpath_handle **vpath_handles,
3159                         u32 vpath_count,
3160                         u8 *mtable,
3161                         u8 *itable,
3162                         u32 itable_size)
3163 {
3164         u32 i, j, action, rts_table;
3165         u64 data0;
3166         u64 data1;
3167         u32 max_entries;
3168         enum vxge_hw_status status = VXGE_HW_OK;
3169         struct __vxge_hw_vpath_handle *vp = vpath_handles[0];
3170
3171         if (vp == NULL) {
3172                 status = VXGE_HW_ERR_INVALID_HANDLE;
3173                 goto exit;
3174         }
3175
3176         max_entries = (((u32)1) << itable_size);
3177
3178         if (vp->vpath->hldev->config.rth_it_type
3179                                 == VXGE_HW_RTH_IT_TYPE_SOLO_IT) {
3180                 action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY;
3181                 rts_table =
3182                         VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT;
3183
3184                 for (j = 0; j < max_entries; j++) {
3185
3186                         data1 = 0;
3187
3188                         data0 =
3189                         VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_BUCKET_DATA(
3190                                 itable[j]);
3191
3192                         status = __vxge_hw_vpath_rts_table_set(vpath_handles[0],
3193                                 action, rts_table, j, data0, data1);
3194
3195                         if (status != VXGE_HW_OK)
3196                                 goto exit;
3197                 }
3198
3199                 for (j = 0; j < max_entries; j++) {
3200
3201                         data1 = 0;
3202
3203                         data0 =
3204                         VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_ENTRY_EN |
3205                         VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_BUCKET_DATA(
3206                                 itable[j]);
3207
3208                         status = __vxge_hw_vpath_rts_table_set(
3209                                 vpath_handles[mtable[itable[j]]], action,
3210                                 rts_table, j, data0, data1);
3211
3212                         if (status != VXGE_HW_OK)
3213                                 goto exit;
3214                 }
3215         } else {
3216                 action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY;
3217                 rts_table =
3218                         VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT;
3219                 for (i = 0; i < vpath_count; i++) {
3220
3221                         for (j = 0; j < max_entries;) {
3222
3223                                 data0 = 0;
3224                                 data1 = 0;
3225
3226                                 while (j < max_entries) {
3227                                         if (mtable[itable[j]] != i) {
3228                                                 j++;
3229                                                 continue;
3230                                         }
3231                                         vxge_hw_rts_rth_data0_data1_get(j,
3232                                                 &data0, &data1, 1, itable);
3233                                         j++;
3234                                         break;
3235                                 }
3236
3237                                 while (j < max_entries) {
3238                                         if (mtable[itable[j]] != i) {
3239                                                 j++;
3240                                                 continue;
3241                                         }
3242                                         vxge_hw_rts_rth_data0_data1_get(j,
3243                                                 &data0, &data1, 2, itable);
3244                                         j++;
3245                                         break;
3246                                 }
3247
3248                                 while (j < max_entries) {
3249                                         if (mtable[itable[j]] != i) {
3250                                                 j++;
3251                                                 continue;
3252                                         }
3253                                         vxge_hw_rts_rth_data0_data1_get(j,
3254                                                 &data0, &data1, 3, itable);
3255                                         j++;
3256                                         break;
3257                                 }
3258
3259                                 while (j < max_entries) {
3260                                         if (mtable[itable[j]] != i) {
3261                                                 j++;
3262                                                 continue;
3263                                         }
3264                                         vxge_hw_rts_rth_data0_data1_get(j,
3265                                                 &data0, &data1, 4, itable);
3266                                         j++;
3267                                         break;
3268                                 }
3269
3270                                 if (data0 != 0) {
3271                                         status = __vxge_hw_vpath_rts_table_set(
3272                                                         vpath_handles[i],
3273                                                         action, rts_table,
3274                                                         0, data0, data1);
3275
3276                                         if (status != VXGE_HW_OK)
3277                                                 goto exit;
3278                                 }
3279                         }
3280                 }
3281         }
3282 exit:
3283         return status;
3284 }
3285
3286 /**
3287  * vxge_hw_vpath_check_leak - Check for memory leak
3288  * @ringh: Handle to the ring object used for receive
3289  *
3290  * If PRC_RXD_DOORBELL_VPn.NEW_QW_CNT is larger or equal to
3291  * PRC_CFG6_VPn.RXD_SPAT then a leak has occurred.
3292  * Returns: VXGE_HW_FAIL, if leak has occurred.
3293  *
3294  */
3295 enum vxge_hw_status
3296 vxge_hw_vpath_check_leak(struct __vxge_hw_ring *ring)
3297 {
3298         enum vxge_hw_status status = VXGE_HW_OK;
3299         u64 rxd_new_count, rxd_spat;
3300
3301         if (ring == NULL)
3302                 return status;
3303
3304         rxd_new_count = readl(&ring->vp_reg->prc_rxd_doorbell);
3305         rxd_spat = readq(&ring->vp_reg->prc_cfg6);
3306         rxd_spat = VXGE_HW_PRC_CFG6_RXD_SPAT(rxd_spat);
3307
3308         if (rxd_new_count >= rxd_spat)
3309                 status = VXGE_HW_FAIL;
3310
3311         return status;
3312 }
3313
3314 /*
3315  * __vxge_hw_vpath_mgmt_read
3316  * This routine reads the vpath_mgmt registers
3317  */
3318 static enum vxge_hw_status
3319 __vxge_hw_vpath_mgmt_read(
3320         struct __vxge_hw_device *hldev,
3321         struct __vxge_hw_virtualpath *vpath)
3322 {
3323         u32 i, mtu = 0, max_pyld = 0;
3324         u64 val64;
3325         enum vxge_hw_status status = VXGE_HW_OK;
3326
3327         for (i = 0; i < VXGE_HW_MAC_MAX_MAC_PORT_ID; i++) {
3328
3329                 val64 = readq(&vpath->vpmgmt_reg->
3330                                 rxmac_cfg0_port_vpmgmt_clone[i]);
3331                 max_pyld =
3332                         (u32)
3333                         VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_GET_MAX_PYLD_LEN
3334                         (val64);
3335                 if (mtu < max_pyld)
3336                         mtu = max_pyld;
3337         }
3338
3339         vpath->max_mtu = mtu + VXGE_HW_MAC_HEADER_MAX_SIZE;
3340
3341         val64 = readq(&vpath->vpmgmt_reg->xmac_vsport_choices_vp);
3342
3343         for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
3344                 if (val64 & vxge_mBIT(i))
3345                         vpath->vsport_number = i;
3346         }
3347
3348         val64 = readq(&vpath->vpmgmt_reg->xgmac_gen_status_vpmgmt_clone);
3349
3350         if (val64 & VXGE_HW_XGMAC_GEN_STATUS_VPMGMT_CLONE_XMACJ_NTWK_OK)
3351                 VXGE_HW_DEVICE_LINK_STATE_SET(vpath->hldev, VXGE_HW_LINK_UP);
3352         else
3353                 VXGE_HW_DEVICE_LINK_STATE_SET(vpath->hldev, VXGE_HW_LINK_DOWN);
3354
3355         return status;
3356 }
3357
3358 /*
3359  * __vxge_hw_vpath_reset_check - Check if resetting the vpath completed
3360  * This routine checks the vpath_rst_in_prog register to see if
3361  * adapter completed the reset process for the vpath
3362  */
3363 enum vxge_hw_status
3364 __vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath)
3365 {
3366         enum vxge_hw_status status;
3367
3368         status = __vxge_hw_device_register_poll(
3369                         &vpath->hldev->common_reg->vpath_rst_in_prog,
3370                         VXGE_HW_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(
3371                                 1 << (16 - vpath->vp_id)),
3372                         vpath->hldev->config.device_poll_millis);
3373
3374         return status;
3375 }
3376
3377 /*
3378  * __vxge_hw_vpath_reset
3379  * This routine resets the vpath on the device
3380  */
3381 enum vxge_hw_status
3382 __vxge_hw_vpath_reset(struct __vxge_hw_device *hldev, u32 vp_id)
3383 {
3384         u64 val64;
3385         enum vxge_hw_status status = VXGE_HW_OK;
3386
3387         val64 = VXGE_HW_CMN_RSTHDLR_CFG0_SW_RESET_VPATH(1 << (16 - vp_id));
3388
3389         __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32),
3390                                 &hldev->common_reg->cmn_rsthdlr_cfg0);
3391
3392         return status;
3393 }
3394
3395 /*
3396  * __vxge_hw_vpath_sw_reset
3397  * This routine resets the vpath structures
3398  */
3399 enum vxge_hw_status
3400 __vxge_hw_vpath_sw_reset(struct __vxge_hw_device *hldev, u32 vp_id)
3401 {
3402         enum vxge_hw_status status = VXGE_HW_OK;
3403         struct __vxge_hw_virtualpath *vpath;
3404
3405         vpath = (struct __vxge_hw_virtualpath *)&hldev->virtual_paths[vp_id];
3406
3407         if (vpath->ringh) {
3408                 status = __vxge_hw_ring_reset(vpath->ringh);
3409                 if (status != VXGE_HW_OK)
3410                         goto exit;
3411         }
3412
3413         if (vpath->fifoh)
3414                 status = __vxge_hw_fifo_reset(vpath->fifoh);
3415 exit:
3416         return status;
3417 }
3418
3419 /*
3420  * __vxge_hw_vpath_prc_configure
3421  * This routine configures the prc registers of virtual path using the config
3422  * passed
3423  */
3424 void
3425 __vxge_hw_vpath_prc_configure(struct __vxge_hw_device *hldev, u32 vp_id)
3426 {
3427         u64 val64;
3428         struct __vxge_hw_virtualpath *vpath;
3429         struct vxge_hw_vp_config *vp_config;
3430         struct vxge_hw_vpath_reg __iomem *vp_reg;
3431
3432         vpath = &hldev->virtual_paths[vp_id];
3433         vp_reg = vpath->vp_reg;
3434         vp_config = vpath->vp_config;
3435
3436         if (vp_config->ring.enable == VXGE_HW_RING_DISABLE)
3437                 return;
3438
3439         val64 = readq(&vp_reg->prc_cfg1);
3440         val64 |= VXGE_HW_PRC_CFG1_RTI_TINT_DISABLE;
3441         writeq(val64, &vp_reg->prc_cfg1);
3442
3443         val64 = readq(&vpath->vp_reg->prc_cfg6);
3444         val64 |= VXGE_HW_PRC_CFG6_DOORBELL_MODE_EN;
3445         writeq(val64, &vpath->vp_reg->prc_cfg6);
3446
3447         val64 = readq(&vp_reg->prc_cfg7);
3448
3449         if (vpath->vp_config->ring.scatter_mode !=
3450                 VXGE_HW_RING_SCATTER_MODE_USE_FLASH_DEFAULT) {
3451
3452                 val64 &= ~VXGE_HW_PRC_CFG7_SCATTER_MODE(0x3);
3453
3454                 switch (vpath->vp_config->ring.scatter_mode) {
3455                 case VXGE_HW_RING_SCATTER_MODE_A:
3456                         val64 |= VXGE_HW_PRC_CFG7_SCATTER_MODE(
3457                                         VXGE_HW_PRC_CFG7_SCATTER_MODE_A);
3458                         break;
3459                 case VXGE_HW_RING_SCATTER_MODE_B:
3460                         val64 |= VXGE_HW_PRC_CFG7_SCATTER_MODE(
3461                                         VXGE_HW_PRC_CFG7_SCATTER_MODE_B);
3462                         break;
3463                 case VXGE_HW_RING_SCATTER_MODE_C:
3464                         val64 |= VXGE_HW_PRC_CFG7_SCATTER_MODE(
3465                                         VXGE_HW_PRC_CFG7_SCATTER_MODE_C);
3466                         break;
3467                 }
3468         }
3469
3470         writeq(val64, &vp_reg->prc_cfg7);
3471
3472         writeq(VXGE_HW_PRC_CFG5_RXD0_ADD(
3473                                 __vxge_hw_ring_first_block_address_get(
3474                                         vpath->ringh) >> 3), &vp_reg->prc_cfg5);
3475
3476         val64 = readq(&vp_reg->prc_cfg4);
3477         val64 |= VXGE_HW_PRC_CFG4_IN_SVC;
3478         val64 &= ~VXGE_HW_PRC_CFG4_RING_MODE(0x3);
3479
3480         val64 |= VXGE_HW_PRC_CFG4_RING_MODE(
3481                         VXGE_HW_PRC_CFG4_RING_MODE_ONE_BUFFER);
3482
3483         if (hldev->config.rth_en == VXGE_HW_RTH_DISABLE)
3484                 val64 |= VXGE_HW_PRC_CFG4_RTH_DISABLE;
3485         else
3486                 val64 &= ~VXGE_HW_PRC_CFG4_RTH_DISABLE;
3487
3488         writeq(val64, &vp_reg->prc_cfg4);
3489         return;
3490 }
3491
3492 /*
3493  * __vxge_hw_vpath_kdfc_configure
3494  * This routine configures the kdfc registers of virtual path using the
3495  * config passed
3496  */
3497 enum vxge_hw_status
3498 __vxge_hw_vpath_kdfc_configure(struct __vxge_hw_device *hldev, u32 vp_id)
3499 {
3500         u64 val64;
3501         u64 vpath_stride;
3502         enum vxge_hw_status status = VXGE_HW_OK;
3503         struct __vxge_hw_virtualpath *vpath;
3504         struct vxge_hw_vpath_reg __iomem *vp_reg;
3505
3506         vpath = &hldev->virtual_paths[vp_id];
3507         vp_reg = vpath->vp_reg;
3508         status = __vxge_hw_kdfc_swapper_set(hldev->legacy_reg, vp_reg);
3509
3510         if (status != VXGE_HW_OK)
3511                 goto exit;
3512
3513         val64 = readq(&vp_reg->kdfc_drbl_triplet_total);
3514
3515         vpath->max_kdfc_db =
3516                 (u32)VXGE_HW_KDFC_DRBL_TRIPLET_TOTAL_GET_KDFC_MAX_SIZE(
3517                         val64+1)/2;
3518
3519         if (vpath->vp_config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
3520
3521                 vpath->max_nofl_db = vpath->max_kdfc_db;
3522
3523                 if (vpath->max_nofl_db <
3524                         ((vpath->vp_config->fifo.memblock_size /
3525                         (vpath->vp_config->fifo.max_frags *
3526                         sizeof(struct vxge_hw_fifo_txd))) *
3527                         vpath->vp_config->fifo.fifo_blocks)) {
3528
3529                         return VXGE_HW_BADCFG_FIFO_BLOCKS;
3530                 }
3531                 val64 = VXGE_HW_KDFC_FIFO_TRPL_PARTITION_LENGTH_0(
3532                                 (vpath->max_nofl_db*2)-1);
3533         }
3534
3535         writeq(val64, &vp_reg->kdfc_fifo_trpl_partition);
3536
3537         writeq(VXGE_HW_KDFC_FIFO_TRPL_CTRL_TRIPLET_ENABLE,
3538                 &vp_reg->kdfc_fifo_trpl_ctrl);
3539
3540         val64 = readq(&vp_reg->kdfc_trpl_fifo_0_ctrl);
3541
3542         val64 &= ~(VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE(0x3) |
3543                    VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SELECT(0xFF));
3544
3545         val64 |= VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE(
3546                  VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE_NON_OFFLOAD_ONLY) |
3547 #ifndef __BIG_ENDIAN
3548                  VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SWAP_EN |
3549 #endif
3550                  VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SELECT(0);
3551
3552         writeq(val64, &vp_reg->kdfc_trpl_fifo_0_ctrl);
3553         writeq((u64)0, &vp_reg->kdfc_trpl_fifo_0_wb_address);
3554         wmb();
3555         vpath_stride = readq(&hldev->toc_reg->toc_kdfc_vpath_stride);
3556
3557         vpath->nofl_db =
3558                 (struct __vxge_hw_non_offload_db_wrapper __iomem *)
3559                 (hldev->kdfc + (vp_id *
3560                 VXGE_HW_TOC_KDFC_VPATH_STRIDE_GET_TOC_KDFC_VPATH_STRIDE(
3561                                         vpath_stride)));
3562 exit:
3563         return status;
3564 }
3565
3566 /*
3567  * __vxge_hw_vpath_mac_configure
3568  * This routine configures the mac of virtual path using the config passed
3569  */
3570 enum vxge_hw_status
3571 __vxge_hw_vpath_mac_configure(struct __vxge_hw_device *hldev, u32 vp_id)
3572 {
3573         u64 val64;
3574         enum vxge_hw_status status = VXGE_HW_OK;
3575         struct __vxge_hw_virtualpath *vpath;
3576         struct vxge_hw_vp_config *vp_config;
3577         struct vxge_hw_vpath_reg __iomem *vp_reg;
3578
3579         vpath = &hldev->virtual_paths[vp_id];
3580         vp_reg = vpath->vp_reg;
3581         vp_config = vpath->vp_config;
3582
3583         writeq(VXGE_HW_XMAC_VSPORT_CHOICE_VSPORT_NUMBER(
3584                         vpath->vsport_number), &vp_reg->xmac_vsport_choice);
3585
3586         if (vp_config->ring.enable == VXGE_HW_RING_ENABLE) {
3587
3588                 val64 = readq(&vp_reg->xmac_rpa_vcfg);
3589
3590                 if (vp_config->rpa_strip_vlan_tag !=
3591                         VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT) {
3592                         if (vp_config->rpa_strip_vlan_tag)
3593                                 val64 |= VXGE_HW_XMAC_RPA_VCFG_STRIP_VLAN_TAG;
3594                         else
3595                                 val64 &= ~VXGE_HW_XMAC_RPA_VCFG_STRIP_VLAN_TAG;
3596                 }
3597
3598                 writeq(val64, &vp_reg->xmac_rpa_vcfg);
3599                 val64 = readq(&vp_reg->rxmac_vcfg0);
3600
3601                 if (vp_config->mtu !=
3602                                 VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU) {
3603                         val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff);
3604                         if ((vp_config->mtu  +
3605                                 VXGE_HW_MAC_HEADER_MAX_SIZE) < vpath->max_mtu)
3606                                 val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(
3607                                         vp_config->mtu  +
3608                                         VXGE_HW_MAC_HEADER_MAX_SIZE);
3609                         else
3610                                 val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(
3611                                         vpath->max_mtu);
3612                 }
3613
3614                 writeq(val64, &vp_reg->rxmac_vcfg0);
3615
3616                 val64 = readq(&vp_reg->rxmac_vcfg1);
3617
3618                 val64 &= ~(VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_BD_MODE(0x3) |
3619                         VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_EN_MODE);
3620
3621                 if (hldev->config.rth_it_type ==
3622                                 VXGE_HW_RTH_IT_TYPE_MULTI_IT) {
3623                         val64 |= VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_BD_MODE(
3624                                 0x2) |
3625                                 VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_EN_MODE;
3626                 }
3627
3628                 writeq(val64, &vp_reg->rxmac_vcfg1);
3629         }
3630         return status;
3631 }
3632
3633 /*
3634  * __vxge_hw_vpath_tim_configure
3635  * This routine configures the tim registers of virtual path using the config
3636  * passed
3637  */
3638 enum vxge_hw_status
3639 __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id)
3640 {
3641         u64 val64;
3642         enum vxge_hw_status status = VXGE_HW_OK;
3643         struct __vxge_hw_virtualpath *vpath;
3644         struct vxge_hw_vpath_reg __iomem *vp_reg;
3645         struct vxge_hw_vp_config *config;
3646
3647         vpath = &hldev->virtual_paths[vp_id];
3648         vp_reg = vpath->vp_reg;
3649         config = vpath->vp_config;
3650
3651         writeq((u64)0, &vp_reg->tim_dest_addr);
3652         writeq((u64)0, &vp_reg->tim_vpath_map);
3653         writeq((u64)0, &vp_reg->tim_bitmap);
3654         writeq((u64)0, &vp_reg->tim_remap);
3655
3656         if (config->ring.enable == VXGE_HW_RING_ENABLE)
3657                 writeq(VXGE_HW_TIM_RING_ASSN_INT_NUM(
3658                         (vp_id * VXGE_HW_MAX_INTR_PER_VP) +
3659                         VXGE_HW_VPATH_INTR_RX), &vp_reg->tim_ring_assn);
3660
3661         val64 = readq(&vp_reg->tim_pci_cfg);
3662         val64 |= VXGE_HW_TIM_PCI_CFG_ADD_PAD;
3663         writeq(val64, &vp_reg->tim_pci_cfg);
3664
3665         if (config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
3666
3667                 val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
3668
3669                 if (config->tti.btimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
3670                         val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
3671                                 0x3ffffff);
3672                         val64 |= VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
3673                                         config->tti.btimer_val);
3674                 }
3675
3676                 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BITMP_EN;
3677
3678                 if (config->tti.timer_ac_en != VXGE_HW_USE_FLASH_DEFAULT) {
3679                         if (config->tti.timer_ac_en)
3680                                 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
3681                         else
3682                                 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
3683                 }
3684
3685                 if (config->tti.timer_ci_en != VXGE_HW_USE_FLASH_DEFAULT) {
3686                         if (config->tti.timer_ci_en)
3687                                 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
3688                         else
3689                                 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
3690                 }
3691
3692                 if (config->tti.urange_a != VXGE_HW_USE_FLASH_DEFAULT) {
3693                         val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(0x3f);
3694                         val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(
3695                                         config->tti.urange_a);
3696                 }
3697
3698                 if (config->tti.urange_b != VXGE_HW_USE_FLASH_DEFAULT) {
3699                         val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(0x3f);
3700                         val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(
3701                                         config->tti.urange_b);
3702                 }
3703
3704                 if (config->tti.urange_c != VXGE_HW_USE_FLASH_DEFAULT) {
3705                         val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(0x3f);
3706                         val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(
3707                                         config->tti.urange_c);
3708                 }
3709
3710                 writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
3711                 val64 = readq(&vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_TX]);
3712
3713                 if (config->tti.uec_a != VXGE_HW_USE_FLASH_DEFAULT) {
3714                         val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(0xffff);
3715                         val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(
3716                                                 config->tti.uec_a);
3717                 }
3718
3719                 if (config->tti.uec_b != VXGE_HW_USE_FLASH_DEFAULT) {
3720                         val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(0xffff);
3721                         val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(
3722                                                 config->tti.uec_b);
3723                 }
3724
3725                 if (config->tti.uec_c != VXGE_HW_USE_FLASH_DEFAULT) {
3726                         val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(0xffff);
3727                         val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(
3728                                                 config->tti.uec_c);
3729                 }
3730
3731                 if (config->tti.uec_d != VXGE_HW_USE_FLASH_DEFAULT) {
3732                         val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(0xffff);
3733                         val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(
3734                                                 config->tti.uec_d);
3735                 }
3736
3737                 writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_TX]);
3738                 val64 = readq(&vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_TX]);
3739
3740                 if (config->tti.timer_ri_en != VXGE_HW_USE_FLASH_DEFAULT) {
3741                         if (config->tti.timer_ri_en)
3742                                 val64 |= VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
3743                         else
3744                                 val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
3745                 }
3746
3747                 if (config->tti.rtimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
3748                         val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
3749                                         0x3ffffff);
3750                         val64 |= VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
3751                                         config->tti.rtimer_val);
3752                 }
3753
3754                 if (config->tti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) {
3755                         val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f);
3756                         val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(
3757                                         config->tti.util_sel);
3758                 }
3759
3760                 if (config->tti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
3761                         val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
3762                                         0x3ffffff);
3763                         val64 |= VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
3764                                         config->tti.ltimer_val);
3765                 }
3766
3767                 writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_TX]);
3768         }
3769
3770         if (config->ring.enable == VXGE_HW_RING_ENABLE) {
3771
3772                 val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]);
3773
3774                 if (config->rti.btimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
3775                         val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
3776                                         0x3ffffff);
3777                         val64 |= VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
3778                                         config->rti.btimer_val);
3779                 }
3780
3781                 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BITMP_EN;
3782
3783                 if (config->rti.timer_ac_en != VXGE_HW_USE_FLASH_DEFAULT) {
3784                         if (config->rti.timer_ac_en)
3785                                 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
3786                         else
3787                                 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
3788                 }
3789
3790                 if (config->rti.timer_ci_en != VXGE_HW_USE_FLASH_DEFAULT) {
3791                         if (config->rti.timer_ci_en)
3792                                 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
3793                         else
3794                                 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
3795                 }
3796
3797                 if (config->rti.urange_a != VXGE_HW_USE_FLASH_DEFAULT) {
3798                         val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(0x3f);
3799                         val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(
3800                                         config->rti.urange_a);
3801                 }
3802
3803                 if (config->rti.urange_b != VXGE_HW_USE_FLASH_DEFAULT) {
3804                         val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(0x3f);
3805                         val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(
3806                                         config->rti.urange_b);
3807                 }
3808
3809                 if (config->rti.urange_c != VXGE_HW_USE_FLASH_DEFAULT) {
3810                         val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(0x3f);
3811                         val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(
3812                                         config->rti.urange_c);
3813                 }
3814
3815                 writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]);
3816                 val64 = readq(&vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]);
3817
3818                 if (config->rti.uec_a != VXGE_HW_USE_FLASH_DEFAULT) {
3819                         val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(0xffff);
3820                         val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(
3821                                                 config->rti.uec_a);
3822                 }
3823
3824                 if (config->rti.uec_b != VXGE_HW_USE_FLASH_DEFAULT) {
3825                         val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(0xffff);
3826                         val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(
3827                                                 config->rti.uec_b);
3828                 }
3829
3830                 if (config->rti.uec_c != VXGE_HW_USE_FLASH_DEFAULT) {
3831                         val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(0xffff);
3832                         val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(
3833                                                 config->rti.uec_c);
3834                 }
3835
3836                 if (config->rti.uec_d != VXGE_HW_USE_FLASH_DEFAULT) {
3837                         val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(0xffff);
3838                         val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(
3839                                                 config->rti.uec_d);
3840                 }
3841
3842                 writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]);
3843                 val64 = readq(&vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]);
3844
3845                 if (config->rti.timer_ri_en != VXGE_HW_USE_FLASH_DEFAULT) {
3846                         if (config->rti.timer_ri_en)
3847                                 val64 |= VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
3848                         else
3849                                 val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
3850                 }
3851
3852                 if (config->rti.rtimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
3853                         val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
3854                                         0x3ffffff);
3855                         val64 |= VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
3856                                         config->rti.rtimer_val);
3857                 }
3858
3859                 if (config->rti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) {
3860                         val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f);
3861                         val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(
3862                                         config->rti.util_sel);
3863                 }
3864
3865                 if (config->rti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
3866                         val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
3867                                         0x3ffffff);
3868                         val64 |= VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
3869                                         config->rti.ltimer_val);
3870                 }
3871
3872                 writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]);
3873         }
3874
3875         val64 = 0;
3876         writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_EINTA]);
3877         writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_EINTA]);
3878         writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_EINTA]);
3879         writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_BMAP]);
3880         writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_BMAP]);
3881         writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_BMAP]);
3882
3883         return status;
3884 }
3885
3886 void
3887 vxge_hw_vpath_tti_ci_set(struct __vxge_hw_device *hldev, u32 vp_id)
3888 {
3889         struct __vxge_hw_virtualpath *vpath;
3890         struct vxge_hw_vpath_reg __iomem *vp_reg;
3891         struct vxge_hw_vp_config *config;
3892         u64 val64;
3893
3894         vpath = &hldev->virtual_paths[vp_id];
3895         vp_reg = vpath->vp_reg;
3896         config = vpath->vp_config;
3897
3898         if (config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
3899                 val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
3900
3901                 if (config->tti.timer_ci_en != VXGE_HW_TIM_TIMER_CI_ENABLE) {
3902                         config->tti.timer_ci_en = VXGE_HW_TIM_TIMER_CI_ENABLE;
3903                         val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
3904                         writeq(val64,
3905                         &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
3906                 }
3907         }
3908         return;
3909 }
3910 /*
3911  * __vxge_hw_vpath_initialize
3912  * This routine is the final phase of init which initializes the
3913  * registers of the vpath using the configuration passed.
3914  */
3915 enum vxge_hw_status
3916 __vxge_hw_vpath_initialize(struct __vxge_hw_device *hldev, u32 vp_id)
3917 {
3918         u64 val64;
3919         u32 val32;
3920         enum vxge_hw_status status = VXGE_HW_OK;
3921         struct __vxge_hw_virtualpath *vpath;
3922         struct vxge_hw_vpath_reg __iomem *vp_reg;
3923
3924         vpath = &hldev->virtual_paths[vp_id];
3925
3926         if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) {
3927                 status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE;
3928                 goto exit;
3929         }
3930         vp_reg = vpath->vp_reg;
3931
3932         status =  __vxge_hw_vpath_swapper_set(vpath->vp_reg);
3933
3934         if (status != VXGE_HW_OK)
3935                 goto exit;
3936
3937         status =  __vxge_hw_vpath_mac_configure(hldev, vp_id);
3938
3939         if (status != VXGE_HW_OK)
3940                 goto exit;
3941
3942         status =  __vxge_hw_vpath_kdfc_configure(hldev, vp_id);
3943
3944         if (status != VXGE_HW_OK)
3945                 goto exit;
3946
3947         status = __vxge_hw_vpath_tim_configure(hldev, vp_id);
3948
3949         if (status != VXGE_HW_OK)
3950                 goto exit;
3951
3952         val64 = readq(&vp_reg->rtdma_rd_optimization_ctrl);
3953
3954         /* Get MRRS value from device control */
3955         status  = __vxge_hw_vpath_pci_read(vpath, 1, 0x78, &val32);
3956
3957         if (status == VXGE_HW_OK) {
3958                 val32 = (val32 & VXGE_HW_PCI_EXP_DEVCTL_READRQ) >> 12;
3959                 val64 &=
3960                     ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(7));
3961                 val64 |=
3962                     VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(val32);
3963
3964                 val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_WAIT_FOR_SPACE;
3965         }
3966
3967         val64 &= ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY(7));
3968         val64 |=
3969             VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY(
3970                     VXGE_HW_MAX_PAYLOAD_SIZE_512);
3971
3972         val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY_EN;
3973         writeq(val64, &vp_reg->rtdma_rd_optimization_ctrl);
3974
3975 exit:
3976         return status;
3977 }
3978
3979 /*
3980  * __vxge_hw_vp_initialize - Initialize Virtual Path structure
3981  * This routine is the initial phase of init which resets the vpath and
3982  * initializes the software support structures.
3983  */
3984 enum vxge_hw_status
3985 __vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id,
3986                         struct vxge_hw_vp_config *config)
3987 {
3988         struct __vxge_hw_virtualpath *vpath;
3989         enum vxge_hw_status status = VXGE_HW_OK;
3990
3991         if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) {
3992                 status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE;
3993                 goto exit;
3994         }
3995
3996         vpath = &hldev->virtual_paths[vp_id];
3997
3998         vpath->vp_id = vp_id;
3999         vpath->vp_open = VXGE_HW_VP_OPEN;
4000         vpath->hldev = hldev;
4001         vpath->vp_config = config;
4002         vpath->vp_reg = hldev->vpath_reg[vp_id];
4003         vpath->vpmgmt_reg = hldev->vpmgmt_reg[vp_id];
4004
4005         __vxge_hw_vpath_reset(hldev, vp_id);
4006
4007         status = __vxge_hw_vpath_reset_check(vpath);
4008
4009         if (status != VXGE_HW_OK) {
4010                 memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
4011                 goto exit;
4012         }
4013
4014         status = __vxge_hw_vpath_mgmt_read(hldev, vpath);
4015
4016         if (status != VXGE_HW_OK) {
4017                 memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
4018                 goto exit;
4019         }
4020
4021         INIT_LIST_HEAD(&vpath->vpath_handles);
4022
4023         vpath->sw_stats = &hldev->stats.sw_dev_info_stats.vpath_info[vp_id];
4024
4025         VXGE_HW_DEVICE_TIM_INT_MASK_SET(hldev->tim_int_mask0,
4026                 hldev->tim_int_mask1, vp_id);
4027
4028         status = __vxge_hw_vpath_initialize(hldev, vp_id);
4029
4030         if (status != VXGE_HW_OK)
4031                 __vxge_hw_vp_terminate(hldev, vp_id);
4032 exit:
4033         return status;
4034 }
4035
4036 /*
4037  * __vxge_hw_vp_terminate - Terminate Virtual Path structure
4038  * This routine closes all channels it opened and freeup memory
4039  */
4040 void
4041 __vxge_hw_vp_terminate(struct __vxge_hw_device *hldev, u32 vp_id)
4042 {
4043         struct __vxge_hw_virtualpath *vpath;
4044
4045         vpath = &hldev->virtual_paths[vp_id];
4046
4047         if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN)
4048                 goto exit;
4049
4050         VXGE_HW_DEVICE_TIM_INT_MASK_RESET(vpath->hldev->tim_int_mask0,
4051                 vpath->hldev->tim_int_mask1, vpath->vp_id);
4052         hldev->stats.hw_dev_info_stats.vpath_info[vpath->vp_id] = NULL;
4053
4054         memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
4055 exit:
4056         return;
4057 }
4058
4059 /*
4060  * vxge_hw_vpath_mtu_set - Set MTU.
4061  * Set new MTU value. Example, to use jumbo frames:
4062  * vxge_hw_vpath_mtu_set(my_device, 9600);
4063  */
4064 enum vxge_hw_status
4065 vxge_hw_vpath_mtu_set(struct __vxge_hw_vpath_handle *vp, u32 new_mtu)
4066 {
4067         u64 val64;
4068         enum vxge_hw_status status = VXGE_HW_OK;
4069         struct __vxge_hw_virtualpath *vpath;
4070
4071         if (vp == NULL) {
4072                 status = VXGE_HW_ERR_INVALID_HANDLE;
4073                 goto exit;
4074         }
4075         vpath = vp->vpath;
4076
4077         new_mtu += VXGE_HW_MAC_HEADER_MAX_SIZE;
4078
4079         if ((new_mtu < VXGE_HW_MIN_MTU) || (new_mtu > vpath->max_mtu))
4080                 status = VXGE_HW_ERR_INVALID_MTU_SIZE;
4081
4082         val64 = readq(&vpath->vp_reg->rxmac_vcfg0);
4083
4084         val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff);
4085         val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(new_mtu);
4086
4087         writeq(val64, &vpath->vp_reg->rxmac_vcfg0);
4088
4089         vpath->vp_config->mtu = new_mtu - VXGE_HW_MAC_HEADER_MAX_SIZE;
4090
4091 exit:
4092         return status;
4093 }
4094
4095 /*
4096  * vxge_hw_vpath_open - Open a virtual path on a given adapter
4097  * This function is used to open access to virtual path of an
4098  * adapter for offload, GRO operations. This function returns
4099  * synchronously.
4100  */
4101 enum vxge_hw_status
4102 vxge_hw_vpath_open(struct __vxge_hw_device *hldev,
4103                    struct vxge_hw_vpath_attr *attr,
4104                    struct __vxge_hw_vpath_handle **vpath_handle)
4105 {
4106         struct __vxge_hw_virtualpath *vpath;
4107         struct __vxge_hw_vpath_handle *vp;
4108         enum vxge_hw_status status;
4109
4110         vpath = &hldev->virtual_paths[attr->vp_id];
4111
4112         if (vpath->vp_open == VXGE_HW_VP_OPEN) {
4113                 status = VXGE_HW_ERR_INVALID_STATE;
4114                 goto vpath_open_exit1;
4115         }
4116
4117         status = __vxge_hw_vp_initialize(hldev, attr->vp_id,
4118                         &hldev->config.vp_config[attr->vp_id]);
4119
4120         if (status != VXGE_HW_OK)
4121                 goto vpath_open_exit1;
4122
4123         vp = (struct __vxge_hw_vpath_handle *)
4124                 vmalloc(sizeof(struct __vxge_hw_vpath_handle));
4125         if (vp == NULL) {
4126                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
4127                 goto vpath_open_exit2;
4128         }
4129
4130         memset(vp, 0, sizeof(struct __vxge_hw_vpath_handle));
4131
4132         vp->vpath = vpath;
4133
4134         if (vpath->vp_config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
4135                 status = __vxge_hw_fifo_create(vp, &attr->fifo_attr);
4136                 if (status != VXGE_HW_OK)
4137                         goto vpath_open_exit6;
4138         }
4139
4140         if (vpath->vp_config->ring.enable == VXGE_HW_RING_ENABLE) {
4141                 status = __vxge_hw_ring_create(vp, &attr->ring_attr);
4142                 if (status != VXGE_HW_OK)
4143                         goto vpath_open_exit7;
4144
4145                 __vxge_hw_vpath_prc_configure(hldev, attr->vp_id);
4146         }
4147
4148         vpath->fifoh->tx_intr_num =
4149                 (attr->vp_id * VXGE_HW_MAX_INTR_PER_VP)  +
4150                         VXGE_HW_VPATH_INTR_TX;
4151
4152         vpath->stats_block = __vxge_hw_blockpool_block_allocate(hldev,
4153                                 VXGE_HW_BLOCK_SIZE);
4154
4155         if (vpath->stats_block == NULL) {
4156                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
4157                 goto vpath_open_exit8;
4158         }
4159
4160         vpath->hw_stats = (struct vxge_hw_vpath_stats_hw_info *)vpath->
4161                         stats_block->memblock;
4162         memset(vpath->hw_stats, 0,
4163                 sizeof(struct vxge_hw_vpath_stats_hw_info));
4164
4165         hldev->stats.hw_dev_info_stats.vpath_info[attr->vp_id] =
4166                                                 vpath->hw_stats;
4167
4168         vpath->hw_stats_sav =
4169                 &hldev->stats.hw_dev_info_stats.vpath_info_sav[attr->vp_id];
4170         memset(vpath->hw_stats_sav, 0,
4171                         sizeof(struct vxge_hw_vpath_stats_hw_info));
4172
4173         writeq(vpath->stats_block->dma_addr, &vpath->vp_reg->stats_cfg);
4174
4175         status = vxge_hw_vpath_stats_enable(vp);
4176         if (status != VXGE_HW_OK)
4177                 goto vpath_open_exit8;
4178
4179         list_add(&vp->item, &vpath->vpath_handles);
4180
4181         hldev->vpaths_deployed |= vxge_mBIT(vpath->vp_id);
4182
4183         *vpath_handle = vp;
4184
4185         attr->fifo_attr.userdata = vpath->fifoh;
4186         attr->ring_attr.userdata = vpath->ringh;
4187
4188         return VXGE_HW_OK;
4189
4190 vpath_open_exit8:
4191         if (vpath->ringh != NULL)
4192                 __vxge_hw_ring_delete(vp);
4193 vpath_open_exit7:
4194         if (vpath->fifoh != NULL)
4195                 __vxge_hw_fifo_delete(vp);
4196 vpath_open_exit6:
4197         vfree(vp);
4198 vpath_open_exit2:
4199         __vxge_hw_vp_terminate(hldev, attr->vp_id);
4200 vpath_open_exit1:
4201
4202         return status;
4203 }
4204
4205 /**
4206  * vxge_hw_vpath_rx_doorbell_post - Close the handle got from previous vpath
4207  * (vpath) open
4208  * @vp: Handle got from previous vpath open
4209  *
4210  * This function is used to close access to virtual path opened
4211  * earlier.
4212  */
4213 void
4214 vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp)
4215 {
4216         struct __vxge_hw_virtualpath *vpath = NULL;
4217         u64 new_count, val64, val164;
4218         struct __vxge_hw_ring *ring;
4219
4220         vpath = vp->vpath;
4221         ring = vpath->ringh;
4222
4223         new_count = readq(&vpath->vp_reg->rxdmem_size);
4224         new_count &= 0x1fff;
4225         val164 = (VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(new_count));
4226
4227         writeq(VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(val164),
4228                 &vpath->vp_reg->prc_rxd_doorbell);
4229         readl(&vpath->vp_reg->prc_rxd_doorbell);
4230
4231         val164 /= 2;
4232         val64 = readq(&vpath->vp_reg->prc_cfg6);
4233         val64 = VXGE_HW_PRC_CFG6_RXD_SPAT(val64);
4234         val64 &= 0x1ff;
4235
4236         /*
4237          * Each RxD is of 4 qwords
4238          */
4239         new_count -= (val64 + 1);
4240         val64 = min(val164, new_count) / 4;
4241
4242         ring->rxds_limit = min(ring->rxds_limit, val64);
4243         if (ring->rxds_limit < 4)
4244                 ring->rxds_limit = 4;
4245 }
4246
4247 /*
4248  * vxge_hw_vpath_close - Close the handle got from previous vpath (vpath) open
4249  * This function is used to close access to virtual path opened
4250  * earlier.
4251  */
4252 enum vxge_hw_status vxge_hw_vpath_close(struct __vxge_hw_vpath_handle *vp)
4253 {
4254         struct __vxge_hw_virtualpath *vpath = NULL;
4255         struct __vxge_hw_device *devh = NULL;
4256         u32 vp_id = vp->vpath->vp_id;
4257         u32 is_empty = TRUE;
4258         enum vxge_hw_status status = VXGE_HW_OK;
4259
4260         vpath = vp->vpath;
4261         devh = vpath->hldev;
4262
4263         if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
4264                 status = VXGE_HW_ERR_VPATH_NOT_OPEN;
4265                 goto vpath_close_exit;
4266         }
4267
4268         list_del(&vp->item);
4269
4270         if (!list_empty(&vpath->vpath_handles)) {
4271                 list_add(&vp->item, &vpath->vpath_handles);
4272                 is_empty = FALSE;
4273         }
4274
4275         if (!is_empty) {
4276                 status = VXGE_HW_FAIL;
4277                 goto vpath_close_exit;
4278         }
4279
4280         devh->vpaths_deployed &= ~vxge_mBIT(vp_id);
4281
4282         if (vpath->ringh != NULL)
4283                 __vxge_hw_ring_delete(vp);
4284
4285         if (vpath->fifoh != NULL)
4286                 __vxge_hw_fifo_delete(vp);
4287
4288         if (vpath->stats_block != NULL)
4289                 __vxge_hw_blockpool_block_free(devh, vpath->stats_block);
4290
4291         vfree(vp);
4292
4293         __vxge_hw_vp_terminate(devh, vp_id);
4294
4295         vpath->vp_open = VXGE_HW_VP_NOT_OPEN;
4296
4297 vpath_close_exit:
4298         return status;
4299 }
4300
4301 /*
4302  * vxge_hw_vpath_reset - Resets vpath
4303  * This function is used to request a reset of vpath
4304  */
4305 enum vxge_hw_status vxge_hw_vpath_reset(struct __vxge_hw_vpath_handle *vp)
4306 {
4307         enum vxge_hw_status status;
4308         u32 vp_id;
4309         struct __vxge_hw_virtualpath *vpath = vp->vpath;
4310
4311         vp_id = vpath->vp_id;
4312
4313         if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
4314                 status = VXGE_HW_ERR_VPATH_NOT_OPEN;
4315                 goto exit;
4316         }
4317
4318         status = __vxge_hw_vpath_reset(vpath->hldev, vp_id);
4319         if (status == VXGE_HW_OK)
4320                 vpath->sw_stats->soft_reset_cnt++;
4321 exit:
4322         return status;
4323 }
4324
4325 /*
4326  * vxge_hw_vpath_recover_from_reset - Poll for reset complete and re-initialize.
4327  * This function poll's for the vpath reset completion and re initializes
4328  * the vpath.
4329  */
4330 enum vxge_hw_status
4331 vxge_hw_vpath_recover_from_reset(struct __vxge_hw_vpath_handle *vp)
4332 {
4333         struct __vxge_hw_virtualpath *vpath = NULL;
4334         enum vxge_hw_status status;
4335         struct __vxge_hw_device *hldev;
4336         u32 vp_id;
4337
4338         vp_id = vp->vpath->vp_id;
4339         vpath = vp->vpath;
4340         hldev = vpath->hldev;
4341
4342         if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
4343                 status = VXGE_HW_ERR_VPATH_NOT_OPEN;
4344                 goto exit;
4345         }
4346
4347         status = __vxge_hw_vpath_reset_check(vpath);
4348         if (status != VXGE_HW_OK)
4349                 goto exit;
4350
4351         status = __vxge_hw_vpath_sw_reset(hldev, vp_id);
4352         if (status != VXGE_HW_OK)
4353                 goto exit;
4354
4355         status = __vxge_hw_vpath_initialize(hldev, vp_id);
4356         if (status != VXGE_HW_OK)
4357                 goto exit;
4358
4359         if (vpath->ringh != NULL)
4360                 __vxge_hw_vpath_prc_configure(hldev, vp_id);
4361
4362         memset(vpath->hw_stats, 0,
4363                 sizeof(struct vxge_hw_vpath_stats_hw_info));
4364
4365         memset(vpath->hw_stats_sav, 0,
4366                 sizeof(struct vxge_hw_vpath_stats_hw_info));
4367
4368         writeq(vpath->stats_block->dma_addr,
4369                 &vpath->vp_reg->stats_cfg);
4370
4371         status = vxge_hw_vpath_stats_enable(vp);
4372
4373 exit:
4374         return status;
4375 }
4376
4377 /*
4378  * vxge_hw_vpath_enable - Enable vpath.
4379  * This routine clears the vpath reset thereby enabling a vpath
4380  * to start forwarding frames and generating interrupts.
4381  */
4382 void
4383 vxge_hw_vpath_enable(struct __vxge_hw_vpath_handle *vp)
4384 {
4385         struct __vxge_hw_device *hldev;
4386         u64 val64;
4387
4388         hldev = vp->vpath->hldev;
4389
4390         val64 = VXGE_HW_CMN_RSTHDLR_CFG1_CLR_VPATH_RESET(
4391                 1 << (16 - vp->vpath->vp_id));
4392
4393         __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32),
4394                 &hldev->common_reg->cmn_rsthdlr_cfg1);
4395 }
4396
4397 /*
4398  * vxge_hw_vpath_stats_enable - Enable vpath h/wstatistics.
4399  * Enable the DMA vpath statistics. The function is to be called to re-enable
4400  * the adapter to update stats into the host memory
4401  */
4402 enum vxge_hw_status
4403 vxge_hw_vpath_stats_enable(struct __vxge_hw_vpath_handle *vp)
4404 {
4405         enum vxge_hw_status status = VXGE_HW_OK;
4406         struct __vxge_hw_virtualpath *vpath;
4407
4408         vpath = vp->vpath;
4409
4410         if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
4411                 status = VXGE_HW_ERR_VPATH_NOT_OPEN;
4412                 goto exit;
4413         }
4414
4415         memcpy(vpath->hw_stats_sav, vpath->hw_stats,
4416                         sizeof(struct vxge_hw_vpath_stats_hw_info));
4417
4418         status = __vxge_hw_vpath_stats_get(vpath, vpath->hw_stats);
4419 exit:
4420         return status;
4421 }
4422
4423 /*
4424  * __vxge_hw_vpath_stats_access - Get the statistics from the given location
4425  *                           and offset and perform an operation
4426  */
4427 enum vxge_hw_status
4428 __vxge_hw_vpath_stats_access(struct __vxge_hw_virtualpath *vpath,
4429                              u32 operation, u32 offset, u64 *stat)
4430 {
4431         u64 val64;
4432         enum vxge_hw_status status = VXGE_HW_OK;
4433         struct vxge_hw_vpath_reg __iomem *vp_reg;
4434
4435         if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
4436                 status = VXGE_HW_ERR_VPATH_NOT_OPEN;
4437                 goto vpath_stats_access_exit;
4438         }
4439
4440         vp_reg = vpath->vp_reg;
4441
4442         val64 =  VXGE_HW_XMAC_STATS_ACCESS_CMD_OP(operation) |
4443                  VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE |
4444                  VXGE_HW_XMAC_STATS_ACCESS_CMD_OFFSET_SEL(offset);
4445
4446         status = __vxge_hw_pio_mem_write64(val64,
4447                                 &vp_reg->xmac_stats_access_cmd,
4448                                 VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE,
4449                                 vpath->hldev->config.device_poll_millis);
4450
4451         if ((status == VXGE_HW_OK) && (operation == VXGE_HW_STATS_OP_READ))
4452                 *stat = readq(&vp_reg->xmac_stats_access_data);
4453         else
4454                 *stat = 0;
4455
4456 vpath_stats_access_exit:
4457         return status;
4458 }
4459
4460 /*
4461  * __vxge_hw_vpath_xmac_tx_stats_get - Get the TX Statistics of a vpath
4462  */
4463 enum vxge_hw_status
4464 __vxge_hw_vpath_xmac_tx_stats_get(
4465         struct __vxge_hw_virtualpath *vpath,
4466         struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats)
4467 {
4468         u64 *val64;
4469         int i;
4470         u32 offset = VXGE_HW_STATS_VPATH_TX_OFFSET;
4471         enum vxge_hw_status status = VXGE_HW_OK;
4472
4473         val64 = (u64 *) vpath_tx_stats;
4474
4475         if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
4476                 status = VXGE_HW_ERR_VPATH_NOT_OPEN;
4477                 goto exit;
4478         }
4479
4480         for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_tx_stats) / 8; i++) {
4481                 status = __vxge_hw_vpath_stats_access(vpath,
4482                                         VXGE_HW_STATS_OP_READ,
4483                                         offset, val64);
4484                 if (status != VXGE_HW_OK)
4485                         goto exit;
4486                 offset++;
4487                 val64++;
4488         }
4489 exit:
4490         return status;
4491 }
4492
4493 /*
4494  * __vxge_hw_vpath_xmac_rx_stats_get - Get the RX Statistics of a vpath
4495  */
4496 enum vxge_hw_status
4497 __vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath,
4498                         struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats)
4499 {
4500         u64 *val64;
4501         enum vxge_hw_status status = VXGE_HW_OK;
4502         int i;
4503         u32 offset = VXGE_HW_STATS_VPATH_RX_OFFSET;
4504         val64 = (u64 *) vpath_rx_stats;
4505
4506         if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
4507                 status = VXGE_HW_ERR_VPATH_NOT_OPEN;
4508                 goto exit;
4509         }
4510         for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_rx_stats) / 8; i++) {
4511                 status = __vxge_hw_vpath_stats_access(vpath,
4512                                         VXGE_HW_STATS_OP_READ,
4513                                         offset >> 3, val64);
4514                 if (status != VXGE_HW_OK)
4515                         goto exit;
4516
4517                 offset += 8;
4518                 val64++;
4519         }
4520 exit:
4521         return status;
4522 }
4523
4524 /*
4525  * __vxge_hw_vpath_stats_get - Get the vpath hw statistics.
4526  */
4527 enum vxge_hw_status __vxge_hw_vpath_stats_get(
4528                         struct __vxge_hw_virtualpath *vpath,
4529                         struct vxge_hw_vpath_stats_hw_info *hw_stats)
4530 {
4531         u64 val64;
4532         enum vxge_hw_status status = VXGE_HW_OK;
4533         struct vxge_hw_vpath_reg __iomem *vp_reg;
4534
4535         if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
4536                 status = VXGE_HW_ERR_VPATH_NOT_OPEN;
4537                 goto exit;
4538         }
4539         vp_reg = vpath->vp_reg;
4540
4541         val64 = readq(&vp_reg->vpath_debug_stats0);
4542         hw_stats->ini_num_mwr_sent =
4543                 (u32)VXGE_HW_VPATH_DEBUG_STATS0_GET_INI_NUM_MWR_SENT(val64);
4544
4545         val64 = readq(&vp_reg->vpath_debug_stats1);
4546         hw_stats->ini_num_mrd_sent =
4547                 (u32)VXGE_HW_VPATH_DEBUG_STATS1_GET_INI_NUM_MRD_SENT(val64);
4548
4549         val64 = readq(&vp_reg->vpath_debug_stats2);
4550         hw_stats->ini_num_cpl_rcvd =
4551                 (u32)VXGE_HW_VPATH_DEBUG_STATS2_GET_INI_NUM_CPL_RCVD(val64);
4552
4553         val64 = readq(&vp_reg->vpath_debug_stats3);
4554         hw_stats->ini_num_mwr_byte_sent =
4555                 VXGE_HW_VPATH_DEBUG_STATS3_GET_INI_NUM_MWR_BYTE_SENT(val64);
4556
4557         val64 = readq(&vp_reg->vpath_debug_stats4);
4558         hw_stats->ini_num_cpl_byte_rcvd =
4559                 VXGE_HW_VPATH_DEBUG_STATS4_GET_INI_NUM_CPL_BYTE_RCVD(val64);
4560
4561         val64 = readq(&vp_reg->vpath_debug_stats5);
4562         hw_stats->wrcrdtarb_xoff =
4563                 (u32)VXGE_HW_VPATH_DEBUG_STATS5_GET_WRCRDTARB_XOFF(val64);
4564
4565         val64 = readq(&vp_reg->vpath_debug_stats6);
4566         hw_stats->rdcrdtarb_xoff =
4567                 (u32)VXGE_HW_VPATH_DEBUG_STATS6_GET_RDCRDTARB_XOFF(val64);
4568
4569         val64 = readq(&vp_reg->vpath_genstats_count01);
4570         hw_stats->vpath_genstats_count0 =
4571         (u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT0(
4572                 val64);
4573
4574         val64 = readq(&vp_reg->vpath_genstats_count01);
4575         hw_stats->vpath_genstats_count1 =
4576         (u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT1(
4577                 val64);
4578
4579         val64 = readq(&vp_reg->vpath_genstats_count23);
4580         hw_stats->vpath_genstats_count2 =
4581         (u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT2(
4582                 val64);
4583
4584         val64 = readq(&vp_reg->vpath_genstats_count01);
4585         hw_stats->vpath_genstats_count3 =
4586         (u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT3(
4587                 val64);
4588
4589         val64 = readq(&vp_reg->vpath_genstats_count4);
4590         hw_stats->vpath_genstats_count4 =
4591         (u32)VXGE_HW_VPATH_GENSTATS_COUNT4_GET_PPIF_VPATH_GENSTATS_COUNT4(
4592                 val64);
4593
4594         val64 = readq(&vp_reg->vpath_genstats_count5);
4595         hw_stats->vpath_genstats_count5 =
4596         (u32)VXGE_HW_VPATH_GENSTATS_COUNT5_GET_PPIF_VPATH_GENSTATS_COUNT5(
4597                 val64);
4598
4599         status = __vxge_hw_vpath_xmac_tx_stats_get(vpath, &hw_stats->tx_stats);
4600         if (status != VXGE_HW_OK)
4601                 goto exit;
4602
4603         status = __vxge_hw_vpath_xmac_rx_stats_get(vpath, &hw_stats->rx_stats);
4604         if (status != VXGE_HW_OK)
4605                 goto exit;
4606
4607         VXGE_HW_VPATH_STATS_PIO_READ(
4608                 VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM0_OFFSET);
4609
4610         hw_stats->prog_event_vnum0 =
4611                         (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM0(val64);
4612
4613         hw_stats->prog_event_vnum1 =
4614                         (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM1(val64);
4615
4616         VXGE_HW_VPATH_STATS_PIO_READ(
4617                 VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM2_OFFSET);
4618
4619         hw_stats->prog_event_vnum2 =
4620                         (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM2(val64);
4621
4622         hw_stats->prog_event_vnum3 =
4623                         (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM3(val64);
4624
4625         val64 = readq(&vp_reg->rx_multi_cast_stats);
4626         hw_stats->rx_multi_cast_frame_discard =
4627                 (u16)VXGE_HW_RX_MULTI_CAST_STATS_GET_FRAME_DISCARD(val64);
4628
4629         val64 = readq(&vp_reg->rx_frm_transferred);
4630         hw_stats->rx_frm_transferred =
4631                 (u32)VXGE_HW_RX_FRM_TRANSFERRED_GET_RX_FRM_TRANSFERRED(val64);
4632
4633         val64 = readq(&vp_reg->rxd_returned);
4634         hw_stats->rxd_returned =
4635                 (u16)VXGE_HW_RXD_RETURNED_GET_RXD_RETURNED(val64);
4636
4637         val64 = readq(&vp_reg->dbg_stats_rx_mpa);
4638         hw_stats->rx_mpa_len_fail_frms =
4639                 (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_LEN_FAIL_FRMS(val64);
4640         hw_stats->rx_mpa_mrk_fail_frms =
4641                 (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_MRK_FAIL_FRMS(val64);
4642         hw_stats->rx_mpa_crc_fail_frms =
4643                 (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_CRC_FAIL_FRMS(val64);
4644
4645         val64 = readq(&vp_reg->dbg_stats_rx_fau);
4646         hw_stats->rx_permitted_frms =
4647                 (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_PERMITTED_FRMS(val64);
4648         hw_stats->rx_vp_reset_discarded_frms =
4649         (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_VP_RESET_DISCARDED_FRMS(val64);
4650         hw_stats->rx_wol_frms =
4651                 (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_WOL_FRMS(val64);
4652
4653         val64 = readq(&vp_reg->tx_vp_reset_discarded_frms);
4654         hw_stats->tx_vp_reset_discarded_frms =
4655         (u16)VXGE_HW_TX_VP_RESET_DISCARDED_FRMS_GET_TX_VP_RESET_DISCARDED_FRMS(
4656                 val64);
4657 exit:
4658         return status;
4659 }
4660
4661 /*
4662  * __vxge_hw_blockpool_create - Create block pool
4663  */
4664
4665 enum vxge_hw_status
4666 __vxge_hw_blockpool_create(struct __vxge_hw_device *hldev,
4667                            struct __vxge_hw_blockpool *blockpool,
4668                            u32 pool_size,
4669                            u32 pool_max)
4670 {
4671         u32 i;
4672         struct __vxge_hw_blockpool_entry *entry = NULL;
4673         void *memblock;
4674         dma_addr_t dma_addr;
4675         struct pci_dev *dma_handle;
4676         struct pci_dev *acc_handle;
4677         enum vxge_hw_status status = VXGE_HW_OK;
4678
4679         if (blockpool == NULL) {
4680                 status = VXGE_HW_FAIL;
4681                 goto blockpool_create_exit;
4682         }
4683
4684         blockpool->hldev = hldev;
4685         blockpool->block_size = VXGE_HW_BLOCK_SIZE;
4686         blockpool->pool_size = 0;
4687         blockpool->pool_max = pool_max;
4688         blockpool->req_out = 0;
4689
4690         INIT_LIST_HEAD(&blockpool->free_block_list);
4691         INIT_LIST_HEAD(&blockpool->free_entry_list);
4692
4693         for (i = 0; i < pool_size + pool_max; i++) {
4694                 entry = kzalloc(sizeof(struct __vxge_hw_blockpool_entry),
4695                                 GFP_KERNEL);
4696                 if (entry == NULL) {
4697                         __vxge_hw_blockpool_destroy(blockpool);
4698                         status = VXGE_HW_ERR_OUT_OF_MEMORY;
4699                         goto blockpool_create_exit;
4700                 }
4701                 list_add(&entry->item, &blockpool->free_entry_list);
4702         }
4703
4704         for (i = 0; i < pool_size; i++) {
4705
4706                 memblock = vxge_os_dma_malloc(
4707                                 hldev->pdev,
4708                                 VXGE_HW_BLOCK_SIZE,
4709                                 &dma_handle,
4710                                 &acc_handle);
4711
4712                 if (memblock == NULL) {
4713                         __vxge_hw_blockpool_destroy(blockpool);
4714                         status = VXGE_HW_ERR_OUT_OF_MEMORY;
4715                         goto blockpool_create_exit;
4716                 }
4717
4718                 dma_addr = pci_map_single(hldev->pdev, memblock,
4719                                 VXGE_HW_BLOCK_SIZE, PCI_DMA_BIDIRECTIONAL);
4720
4721                 if (unlikely(pci_dma_mapping_error(hldev->pdev,
4722                                 dma_addr))) {
4723
4724                         vxge_os_dma_free(hldev->pdev, memblock, &acc_handle);
4725                         __vxge_hw_blockpool_destroy(blockpool);
4726                         status = VXGE_HW_ERR_OUT_OF_MEMORY;
4727                         goto blockpool_create_exit;
4728                 }
4729
4730                 if (!list_empty(&blockpool->free_entry_list))
4731                         entry = (struct __vxge_hw_blockpool_entry *)
4732                                 list_first_entry(&blockpool->free_entry_list,
4733                                         struct __vxge_hw_blockpool_entry,
4734                                         item);
4735
4736                 if (entry == NULL)
4737                         entry =
4738                             kzalloc(sizeof(struct __vxge_hw_blockpool_entry),
4739                                         GFP_KERNEL);
4740                 if (entry != NULL) {
4741                         list_del(&entry->item);
4742                         entry->length = VXGE_HW_BLOCK_SIZE;
4743                         entry->memblock = memblock;
4744                         entry->dma_addr = dma_addr;
4745                         entry->acc_handle = acc_handle;
4746                         entry->dma_handle = dma_handle;
4747                         list_add(&entry->item,
4748                                           &blockpool->free_block_list);
4749                         blockpool->pool_size++;
4750                 } else {
4751                         __vxge_hw_blockpool_destroy(blockpool);
4752                         status = VXGE_HW_ERR_OUT_OF_MEMORY;
4753                         goto blockpool_create_exit;
4754                 }
4755         }
4756
4757 blockpool_create_exit:
4758         return status;
4759 }
4760
4761 /*
4762  * __vxge_hw_blockpool_destroy - Deallocates the block pool
4763  */
4764
4765 void __vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool)
4766 {
4767
4768         struct __vxge_hw_device *hldev;
4769         struct list_head *p, *n;
4770         u16 ret;
4771
4772         if (blockpool == NULL) {
4773                 ret = 1;
4774                 goto exit;
4775         }
4776
4777         hldev = blockpool->hldev;
4778
4779         list_for_each_safe(p, n, &blockpool->free_block_list) {
4780
4781                 pci_unmap_single(hldev->pdev,
4782                         ((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
4783                         ((struct __vxge_hw_blockpool_entry *)p)->length,
4784                         PCI_DMA_BIDIRECTIONAL);
4785
4786                 vxge_os_dma_free(hldev->pdev,
4787                         ((struct __vxge_hw_blockpool_entry *)p)->memblock,
4788                         &((struct __vxge_hw_blockpool_entry *) p)->acc_handle);
4789
4790                 list_del(
4791                         &((struct __vxge_hw_blockpool_entry *)p)->item);
4792                 kfree(p);
4793                 blockpool->pool_size--;
4794         }
4795
4796         list_for_each_safe(p, n, &blockpool->free_entry_list) {
4797                 list_del(
4798                         &((struct __vxge_hw_blockpool_entry *)p)->item);
4799                 kfree((void *)p);
4800         }
4801         ret = 0;
4802 exit:
4803         return;
4804 }
4805
4806 /*
4807  * __vxge_hw_blockpool_blocks_add - Request additional blocks
4808  */
4809 static
4810 void __vxge_hw_blockpool_blocks_add(struct __vxge_hw_blockpool *blockpool)
4811 {
4812         u32 nreq = 0, i;
4813
4814         if ((blockpool->pool_size  +  blockpool->req_out) <
4815                 VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE) {
4816                 nreq = VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE;
4817                 blockpool->req_out += nreq;
4818         }
4819
4820         for (i = 0; i < nreq; i++)
4821                 vxge_os_dma_malloc_async(
4822                         ((struct __vxge_hw_device *)blockpool->hldev)->pdev,
4823                         blockpool->hldev, VXGE_HW_BLOCK_SIZE);
4824 }
4825
4826 /*
4827  * __vxge_hw_blockpool_blocks_remove - Free additional blocks
4828  */
4829 static
4830 void __vxge_hw_blockpool_blocks_remove(struct __vxge_hw_blockpool *blockpool)
4831 {
4832         struct list_head *p, *n;
4833
4834         list_for_each_safe(p, n, &blockpool->free_block_list) {
4835
4836                 if (blockpool->pool_size < blockpool->pool_max)
4837                         break;
4838
4839                 pci_unmap_single(
4840                         ((struct __vxge_hw_device *)blockpool->hldev)->pdev,
4841                         ((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
4842                         ((struct __vxge_hw_blockpool_entry *)p)->length,
4843                         PCI_DMA_BIDIRECTIONAL);
4844
4845                 vxge_os_dma_free(
4846                         ((struct __vxge_hw_device *)blockpool->hldev)->pdev,
4847                         ((struct __vxge_hw_blockpool_entry *)p)->memblock,
4848                         &((struct __vxge_hw_blockpool_entry *)p)->acc_handle);
4849
4850                 list_del(&((struct __vxge_hw_blockpool_entry *)p)->item);
4851
4852                 list_add(p, &blockpool->free_entry_list);
4853
4854                 blockpool->pool_size--;
4855
4856         }
4857 }
4858
4859 /*
4860  * vxge_hw_blockpool_block_add - callback for vxge_os_dma_malloc_async
4861  * Adds a block to block pool
4862  */
4863 void vxge_hw_blockpool_block_add(
4864                         struct __vxge_hw_device *devh,
4865                         void *block_addr,
4866                         u32 length,
4867                         struct pci_dev *dma_h,
4868                         struct pci_dev *acc_handle)
4869 {
4870         struct __vxge_hw_blockpool  *blockpool;
4871         struct __vxge_hw_blockpool_entry  *entry = NULL;
4872         dma_addr_t dma_addr;
4873         enum vxge_hw_status status = VXGE_HW_OK;
4874         u32 req_out;
4875
4876         blockpool = &devh->block_pool;
4877
4878         if (block_addr == NULL) {
4879                 blockpool->req_out--;
4880                 status = VXGE_HW_FAIL;
4881                 goto exit;
4882         }
4883
4884         dma_addr = pci_map_single(devh->pdev, block_addr, length,
4885                                 PCI_DMA_BIDIRECTIONAL);
4886
4887         if (unlikely(pci_dma_mapping_error(devh->pdev, dma_addr))) {
4888
4889                 vxge_os_dma_free(devh->pdev, block_addr, &acc_handle);
4890                 blockpool->req_out--;
4891                 status = VXGE_HW_FAIL;
4892                 goto exit;
4893         }
4894
4895
4896         if (!list_empty(&blockpool->free_entry_list))
4897                 entry = (struct __vxge_hw_blockpool_entry *)
4898                         list_first_entry(&blockpool->free_entry_list,
4899                                 struct __vxge_hw_blockpool_entry,
4900                                 item);
4901
4902         if (entry == NULL)
4903                 entry = (struct __vxge_hw_blockpool_entry *)
4904                         vmalloc(sizeof(struct __vxge_hw_blockpool_entry));
4905         else
4906                 list_del(&entry->item);
4907
4908         if (entry != NULL) {
4909                 entry->length = length;
4910                 entry->memblock = block_addr;
4911                 entry->dma_addr = dma_addr;
4912                 entry->acc_handle = acc_handle;
4913                 entry->dma_handle = dma_h;
4914                 list_add(&entry->item, &blockpool->free_block_list);
4915                 blockpool->pool_size++;
4916                 status = VXGE_HW_OK;
4917         } else
4918                 status = VXGE_HW_ERR_OUT_OF_MEMORY;
4919
4920         blockpool->req_out--;
4921
4922         req_out = blockpool->req_out;
4923 exit:
4924         return;
4925 }
4926
4927 /*
4928  * __vxge_hw_blockpool_malloc - Allocate a memory block from pool
4929  * Allocates a block of memory of given size, either from block pool
4930  * or by calling vxge_os_dma_malloc()
4931  */
4932 void *
4933 __vxge_hw_blockpool_malloc(struct __vxge_hw_device *devh, u32 size,
4934                                 struct vxge_hw_mempool_dma *dma_object)
4935 {
4936         struct __vxge_hw_blockpool_entry *entry = NULL;
4937         struct __vxge_hw_blockpool  *blockpool;
4938         void *memblock = NULL;
4939         enum vxge_hw_status status = VXGE_HW_OK;
4940
4941         blockpool = &devh->block_pool;
4942
4943         if (size != blockpool->block_size) {
4944
4945                 memblock = vxge_os_dma_malloc(devh->pdev, size,
4946                                                 &dma_object->handle,
4947                                                 &dma_object->acc_handle);
4948
4949                 if (memblock == NULL) {
4950                         status = VXGE_HW_ERR_OUT_OF_MEMORY;
4951                         goto exit;
4952                 }
4953
4954                 dma_object->addr = pci_map_single(devh->pdev, memblock, size,
4955                                         PCI_DMA_BIDIRECTIONAL);
4956
4957                 if (unlikely(pci_dma_mapping_error(devh->pdev,
4958                                 dma_object->addr))) {
4959                         vxge_os_dma_free(devh->pdev, memblock,
4960                                 &dma_object->acc_handle);
4961                         status = VXGE_HW_ERR_OUT_OF_MEMORY;
4962                         goto exit;
4963                 }
4964
4965         } else {
4966
4967                 if (!list_empty(&blockpool->free_block_list))
4968                         entry = (struct __vxge_hw_blockpool_entry *)
4969                                 list_first_entry(&blockpool->free_block_list,
4970                                         struct __vxge_hw_blockpool_entry,
4971                                         item);
4972
4973                 if (entry != NULL) {
4974                         list_del(&entry->item);
4975                         dma_object->addr = entry->dma_addr;
4976                         dma_object->handle = entry->dma_handle;
4977                         dma_object->acc_handle = entry->acc_handle;
4978                         memblock = entry->memblock;
4979
4980                         list_add(&entry->item,
4981                                 &blockpool->free_entry_list);
4982                         blockpool->pool_size--;
4983                 }
4984
4985                 if (memblock != NULL)
4986                         __vxge_hw_blockpool_blocks_add(blockpool);
4987         }
4988 exit:
4989         return memblock;
4990 }
4991
4992 /*
4993  * __vxge_hw_blockpool_free - Frees the memory allcoated with
4994                                 __vxge_hw_blockpool_malloc
4995  */
4996 void
4997 __vxge_hw_blockpool_free(struct __vxge_hw_device *devh,
4998                         void *memblock, u32 size,
4999                         struct vxge_hw_mempool_dma *dma_object)
5000 {
5001         struct __vxge_hw_blockpool_entry *entry = NULL;
5002         struct __vxge_hw_blockpool  *blockpool;
5003         enum vxge_hw_status status = VXGE_HW_OK;
5004
5005         blockpool = &devh->block_pool;
5006
5007         if (size != blockpool->block_size) {
5008                 pci_unmap_single(devh->pdev, dma_object->addr, size,
5009                         PCI_DMA_BIDIRECTIONAL);
5010                 vxge_os_dma_free(devh->pdev, memblock, &dma_object->acc_handle);
5011         } else {
5012
5013                 if (!list_empty(&blockpool->free_entry_list))
5014                         entry = (struct __vxge_hw_blockpool_entry *)
5015                                 list_first_entry(&blockpool->free_entry_list,
5016                                         struct __vxge_hw_blockpool_entry,
5017                                         item);
5018
5019                 if (entry == NULL)
5020                         entry = (struct __vxge_hw_blockpool_entry *)
5021                                 vmalloc(sizeof(
5022                                         struct __vxge_hw_blockpool_entry));
5023                 else
5024                         list_del(&entry->item);
5025
5026                 if (entry != NULL) {
5027                         entry->length = size;
5028                         entry->memblock = memblock;
5029                         entry->dma_addr = dma_object->addr;
5030                         entry->acc_handle = dma_object->acc_handle;
5031                         entry->dma_handle = dma_object->handle;
5032                         list_add(&entry->item,
5033                                         &blockpool->free_block_list);
5034                         blockpool->pool_size++;
5035                         status = VXGE_HW_OK;
5036                 } else
5037                         status = VXGE_HW_ERR_OUT_OF_MEMORY;
5038
5039                 if (status == VXGE_HW_OK)
5040                         __vxge_hw_blockpool_blocks_remove(blockpool);
5041         }
5042
5043         return;
5044 }
5045
5046 /*
5047  * __vxge_hw_blockpool_block_allocate - Allocates a block from block pool
5048  * This function allocates a block from block pool or from the system
5049  */
5050 struct __vxge_hw_blockpool_entry *
5051 __vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *devh, u32 size)
5052 {
5053         struct __vxge_hw_blockpool_entry *entry = NULL;
5054         struct __vxge_hw_blockpool  *blockpool;
5055
5056         blockpool = &devh->block_pool;
5057
5058         if (size == blockpool->block_size) {
5059
5060                 if (!list_empty(&blockpool->free_block_list))
5061                         entry = (struct __vxge_hw_blockpool_entry *)
5062                                 list_first_entry(&blockpool->free_block_list,
5063                                         struct __vxge_hw_blockpool_entry,
5064                                         item);
5065
5066                 if (entry != NULL) {
5067                         list_del(&entry->item);
5068                         blockpool->pool_size--;
5069                 }
5070         }
5071
5072         if (entry != NULL)
5073                 __vxge_hw_blockpool_blocks_add(blockpool);
5074
5075         return entry;
5076 }
5077
5078 /*
5079  * __vxge_hw_blockpool_block_free - Frees a block from block pool
5080  * @devh: Hal device
5081  * @entry: Entry of block to be freed
5082  *
5083  * This function frees a block from block pool
5084  */
5085 void
5086 __vxge_hw_blockpool_block_free(struct __vxge_hw_device *devh,
5087                         struct __vxge_hw_blockpool_entry *entry)
5088 {
5089         struct __vxge_hw_blockpool  *blockpool;
5090
5091         blockpool = &devh->block_pool;
5092
5093         if (entry->length == blockpool->block_size) {
5094                 list_add(&entry->item, &blockpool->free_block_list);
5095                 blockpool->pool_size++;
5096         }
5097
5098         __vxge_hw_blockpool_blocks_remove(blockpool);
5099
5100         return;
5101 }