aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/enic/vnic_dev.c
diff options
context:
space:
mode:
authorVasanthy Kolluri <vkolluri@cisco.com>2011-06-17 03:56:48 -0400
committerDavid S. Miller <davem@davemloft.net>2011-06-30 23:43:38 -0400
commitea7ea65a3b37bf207d5c352ac6254506b3dc3901 (patch)
tree5eed17f071404155e7a76f8f3415bf031a4d656a /drivers/net/enic/vnic_dev.c
parent3fa2a1df909482cc234524906e4bd30dee3514df (diff)
enic: Add support to configure hardware interrupt coalesce timers in a platform independent way
enic driver and the underlying hardware use different units for representing the interrupt coalesce timer. Driver converts the interrupt coalesce timer in usec to hardware cycles while setting the relevant hardware registers. The conversion factor can be different for each of the adapter hardware types. So it is dynamically learnt from the adapter firmware using the devcmd CMD_INTR_COAL_CONVERT. This allows the driver to configure the hardware interrupt coalesce timers in a platform independent way. Signed-off-by: Danny Guo <dannguo@cisco.com> Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com> Signed-off-by: Roopa Prabhu <roprabhu@cisco.com> Signed-off-by: David Wang <dwang2@cisco.com> Signed-off-by: David S. Miller <davem@conan.davemloft.net>
Diffstat (limited to 'drivers/net/enic/vnic_dev.c')
-rw-r--r--drivers/net/enic/vnic_dev.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index 68f24ae860ae..8c4c8cf486f6 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -40,6 +40,12 @@ struct vnic_res {
40 unsigned int count; 40 unsigned int count;
41}; 41};
42 42
43struct vnic_intr_coal_timer_info {
44 u32 mul;
45 u32 div;
46 u32 max_usec;
47};
48
43struct vnic_dev { 49struct vnic_dev {
44 void *priv; 50 void *priv;
45 struct pci_dev *pdev; 51 struct pci_dev *pdev;
@@ -58,6 +64,7 @@ struct vnic_dev {
58 enum vnic_proxy_type proxy; 64 enum vnic_proxy_type proxy;
59 u32 proxy_index; 65 u32 proxy_index;
60 u64 args[VNIC_DEVCMD_NARGS]; 66 u64 args[VNIC_DEVCMD_NARGS];
67 struct vnic_intr_coal_timer_info intr_coal_timer_info;
61}; 68};
62 69
63#define VNIC_MAX_RES_HDR_SIZE \ 70#define VNIC_MAX_RES_HDR_SIZE \
@@ -794,6 +801,42 @@ int vnic_dev_deinit(struct vnic_dev *vdev)
794 return vnic_dev_cmd(vdev, CMD_DEINIT, &a0, &a1, wait); 801 return vnic_dev_cmd(vdev, CMD_DEINIT, &a0, &a1, wait);
795} 802}
796 803
804void vnic_dev_intr_coal_timer_info_default(struct vnic_dev *vdev)
805{
806 /* Default: hardware intr coal timer is in units of 1.5 usecs */
807 vdev->intr_coal_timer_info.mul = 2;
808 vdev->intr_coal_timer_info.div = 3;
809 vdev->intr_coal_timer_info.max_usec =
810 vnic_dev_intr_coal_timer_hw_to_usec(vdev, 0xffff);
811}
812
813int vnic_dev_intr_coal_timer_info(struct vnic_dev *vdev)
814{
815 int wait = 1000;
816 int err;
817
818 memset(vdev->args, 0, sizeof(vdev->args));
819
820 err = _vnic_dev_cmd(vdev, CMD_INTR_COAL_CONVERT, wait);
821
822 /* Use defaults when firmware doesn't support the devcmd at all or
823 * supports it for only specific hardware
824 */
825 if ((err == ERR_ECMDUNKNOWN) ||
826 (!err && !(vdev->args[0] && vdev->args[1] && vdev->args[2]))) {
827 pr_warning("Using default conversion factor for "
828 "interrupt coalesce timer\n");
829 vnic_dev_intr_coal_timer_info_default(vdev);
830 return 0;
831 }
832
833 vdev->intr_coal_timer_info.mul = (u32) vdev->args[0];
834 vdev->intr_coal_timer_info.div = (u32) vdev->args[1];
835 vdev->intr_coal_timer_info.max_usec = (u32) vdev->args[2];
836
837 return err;
838}
839
797int vnic_dev_link_status(struct vnic_dev *vdev) 840int vnic_dev_link_status(struct vnic_dev *vdev)
798{ 841{
799 if (!vnic_dev_notify_ready(vdev)) 842 if (!vnic_dev_notify_ready(vdev))
@@ -838,6 +881,23 @@ enum vnic_dev_intr_mode vnic_dev_get_intr_mode(
838 return vdev->intr_mode; 881 return vdev->intr_mode;
839} 882}
840 883
884u32 vnic_dev_intr_coal_timer_usec_to_hw(struct vnic_dev *vdev, u32 usec)
885{
886 return (usec * vdev->intr_coal_timer_info.mul) /
887 vdev->intr_coal_timer_info.div;
888}
889
890u32 vnic_dev_intr_coal_timer_hw_to_usec(struct vnic_dev *vdev, u32 hw_cycles)
891{
892 return (hw_cycles * vdev->intr_coal_timer_info.div) /
893 vdev->intr_coal_timer_info.mul;
894}
895
896u32 vnic_dev_get_intr_coal_timer_max(struct vnic_dev *vdev)
897{
898 return vdev->intr_coal_timer_info.max_usec;
899}
900
841void vnic_dev_unregister(struct vnic_dev *vdev) 901void vnic_dev_unregister(struct vnic_dev *vdev)
842{ 902{
843 if (vdev) { 903 if (vdev) {