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