Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 255994
b: refs/heads/master
c: ea7ea65
h: refs/heads/master
v: v3
  • Loading branch information
Vasanthy Kolluri authored and David S. Miller committed Jul 1, 2011
1 parent f403763 commit a0a8151
Show file tree
Hide file tree
Showing 12 changed files with 123 additions and 27 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3fa2a1df909482cc234524906e4bd30dee3514df
refs/heads/master: ea7ea65a3b37bf207d5c352ac6254506b3dc3901
2 changes: 1 addition & 1 deletion trunk/drivers/net/enic/enic.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

#define DRV_NAME "enic"
#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
#define DRV_VERSION "2.1.1.20"
#define DRV_VERSION "2.1.1.24"
#define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc"

#define ENIC_BARS_MAX 6
Expand Down
11 changes: 11 additions & 0 deletions trunk/drivers/net/enic/enic_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,17 @@ int enic_dev_disable(struct enic *enic)
return err;
}

int enic_dev_intr_coal_timer_info(struct enic *enic)
{
int err;

spin_lock(&enic->devcmd_lock);
err = vnic_dev_intr_coal_timer_info(enic->vdev);
spin_unlock(&enic->devcmd_lock);

return err;
}

int enic_vnic_dev_deinit(struct enic *enic)
{
int err;
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/net/enic/enic_dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ int enic_dev_hang_notify(struct enic *enic);
int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic);
int enic_dev_enable(struct enic *enic);
int enic_dev_disable(struct enic *enic);
int enic_dev_intr_coal_timer_info(struct enic *enic);
int enic_vnic_dev_deinit(struct enic *enic);
int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp);
int enic_dev_deinit_done(struct enic *enic, int *status);
Expand Down
26 changes: 16 additions & 10 deletions trunk/drivers/net/enic/enic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,12 +284,10 @@ static int enic_set_coalesce(struct net_device *netdev,
u32 rx_coalesce_usecs;
unsigned int i, intr;

tx_coalesce_usecs = min_t(u32,
INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX),
ecmd->tx_coalesce_usecs);
rx_coalesce_usecs = min_t(u32,
INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX),
ecmd->rx_coalesce_usecs);
tx_coalesce_usecs = min_t(u32, ecmd->tx_coalesce_usecs,
vnic_dev_get_intr_coal_timer_max(enic->vdev));
rx_coalesce_usecs = min_t(u32, ecmd->rx_coalesce_usecs,
vnic_dev_get_intr_coal_timer_max(enic->vdev));

switch (vnic_dev_get_intr_mode(enic->vdev)) {
case VNIC_DEV_INTR_MODE_INTX:
Expand All @@ -298,26 +296,26 @@ static int enic_set_coalesce(struct net_device *netdev,

intr = enic_legacy_io_intr();
vnic_intr_coalescing_timer_set(&enic->intr[intr],
INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
tx_coalesce_usecs);
break;
case VNIC_DEV_INTR_MODE_MSI:
if (tx_coalesce_usecs != rx_coalesce_usecs)
return -EINVAL;

vnic_intr_coalescing_timer_set(&enic->intr[0],
INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
tx_coalesce_usecs);
break;
case VNIC_DEV_INTR_MODE_MSIX:
for (i = 0; i < enic->wq_count; i++) {
intr = enic_msix_wq_intr(enic, i);
vnic_intr_coalescing_timer_set(&enic->intr[intr],
INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
tx_coalesce_usecs);
}

for (i = 0; i < enic->rq_count; i++) {
intr = enic_msix_rq_intr(enic, i);
vnic_intr_coalescing_timer_set(&enic->intr[intr],
INTR_COALESCE_USEC_TO_HW(rx_coalesce_usecs));
rx_coalesce_usecs);
}

break;
Expand Down Expand Up @@ -2175,6 +2173,14 @@ static int enic_dev_init(struct enic *enic)
unsigned int i;
int err;

/* Get interrupt coalesce timer info */
err = enic_dev_intr_coal_timer_info(enic);
if (err) {
dev_warn(dev, "Using default conversion factor for "
"interrupt coalesce timer\n");
vnic_dev_intr_coal_timer_info_default(enic->vdev);
}

/* Get vNIC configuration
*/

Expand Down
7 changes: 3 additions & 4 deletions trunk/drivers/net/enic/enic_res.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,8 @@ int enic_get_vnic_config(struct enic *enic)
max_t(u16, ENIC_MIN_MTU,
c->mtu));

c->intr_timer_usec = min_t(u32,
INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX),
c->intr_timer_usec);
c->intr_timer_usec = min_t(u32, c->intr_timer_usec,
vnic_dev_get_intr_coal_timer_max(enic->vdev));

dev_info(enic_get_dev(enic),
"vNIC MAC addr %pM wq/rq %d/%d mtu %d\n",
Expand Down Expand Up @@ -303,7 +302,7 @@ void enic_init_vnic_resources(struct enic *enic)

for (i = 0; i < enic->intr_count; i++) {
vnic_intr_init(&enic->intr[i],
INTR_COALESCE_USEC_TO_HW(enic->config.intr_timer_usec),
enic->config.intr_timer_usec,
enic->config.intr_timer_type,
mask_on_assertion);
}
Expand Down
60 changes: 60 additions & 0 deletions trunk/drivers/net/enic/vnic_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ struct vnic_res {
unsigned int count;
};

struct vnic_intr_coal_timer_info {
u32 mul;
u32 div;
u32 max_usec;
};

struct vnic_dev {
void *priv;
struct pci_dev *pdev;
Expand All @@ -58,6 +64,7 @@ struct vnic_dev {
enum vnic_proxy_type proxy;
u32 proxy_index;
u64 args[VNIC_DEVCMD_NARGS];
struct vnic_intr_coal_timer_info intr_coal_timer_info;
};

#define VNIC_MAX_RES_HDR_SIZE \
Expand Down Expand Up @@ -794,6 +801,42 @@ int vnic_dev_deinit(struct vnic_dev *vdev)
return vnic_dev_cmd(vdev, CMD_DEINIT, &a0, &a1, wait);
}

void vnic_dev_intr_coal_timer_info_default(struct vnic_dev *vdev)
{
/* Default: hardware intr coal timer is in units of 1.5 usecs */
vdev->intr_coal_timer_info.mul = 2;
vdev->intr_coal_timer_info.div = 3;
vdev->intr_coal_timer_info.max_usec =
vnic_dev_intr_coal_timer_hw_to_usec(vdev, 0xffff);
}

int vnic_dev_intr_coal_timer_info(struct vnic_dev *vdev)
{
int wait = 1000;
int err;

memset(vdev->args, 0, sizeof(vdev->args));

err = _vnic_dev_cmd(vdev, CMD_INTR_COAL_CONVERT, wait);

/* Use defaults when firmware doesn't support the devcmd at all or
* supports it for only specific hardware
*/
if ((err == ERR_ECMDUNKNOWN) ||
(!err && !(vdev->args[0] && vdev->args[1] && vdev->args[2]))) {
pr_warning("Using default conversion factor for "
"interrupt coalesce timer\n");
vnic_dev_intr_coal_timer_info_default(vdev);
return 0;
}

vdev->intr_coal_timer_info.mul = (u32) vdev->args[0];
vdev->intr_coal_timer_info.div = (u32) vdev->args[1];
vdev->intr_coal_timer_info.max_usec = (u32) vdev->args[2];

return err;
}

int vnic_dev_link_status(struct vnic_dev *vdev)
{
if (!vnic_dev_notify_ready(vdev))
Expand Down Expand Up @@ -838,6 +881,23 @@ enum vnic_dev_intr_mode vnic_dev_get_intr_mode(
return vdev->intr_mode;
}

u32 vnic_dev_intr_coal_timer_usec_to_hw(struct vnic_dev *vdev, u32 usec)
{
return (usec * vdev->intr_coal_timer_info.mul) /
vdev->intr_coal_timer_info.div;
}

u32 vnic_dev_intr_coal_timer_hw_to_usec(struct vnic_dev *vdev, u32 hw_cycles)
{
return (hw_cycles * vdev->intr_coal_timer_info.div) /
vdev->intr_coal_timer_info.mul;
}

u32 vnic_dev_get_intr_coal_timer_max(struct vnic_dev *vdev)
{
return vdev->intr_coal_timer_info.max_usec;
}

void vnic_dev_unregister(struct vnic_dev *vdev)
{
if (vdev) {
Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/net/enic/vnic_dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,16 @@ int vnic_dev_open(struct vnic_dev *vdev, int arg);
int vnic_dev_open_done(struct vnic_dev *vdev, int *done);
int vnic_dev_init(struct vnic_dev *vdev, int arg);
int vnic_dev_deinit(struct vnic_dev *vdev);
void vnic_dev_intr_coal_timer_info_default(struct vnic_dev *vdev);
int vnic_dev_intr_coal_timer_info(struct vnic_dev *vdev);
int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg);
int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done);
void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
enum vnic_dev_intr_mode intr_mode);
enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev);
u32 vnic_dev_intr_coal_timer_usec_to_hw(struct vnic_dev *vdev, u32 usec);
u32 vnic_dev_intr_coal_timer_hw_to_usec(struct vnic_dev *vdev, u32 hw_cycles);
u32 vnic_dev_get_intr_coal_timer_max(struct vnic_dev *vdev);
void vnic_dev_unregister(struct vnic_dev *vdev);
int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev,
u8 ig_vlan_rewrite_mode);
Expand Down
19 changes: 19 additions & 0 deletions trunk/drivers/net/enic/vnic_devcmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,25 @@ enum vnic_devcmd_cmd {
* ERR_EINPROGRESS - command in a0 is still in progress
*/
CMD_STATUS = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 49),

/*
* Returns interrupt coalescing timer conversion factors.
* After calling this devcmd, ENIC driver can convert
* interrupt coalescing timer in usec into CPU cycles as follows:
*
* intr_timer_cycles = intr_timer_usec * multiplier / divisor
*
* Interrupt coalescing timer in usecs can be obtained from
* CPU cycles as follows:
*
* intr_timer_usec = intr_timer_cycles * divisor / multiplier
*
* in: none
* out: (u32)a0 = multiplier
* (u32)a1 = divisor
* (u32)a2 = maximum timer value in usec
*/
CMD_INTR_COAL_CONVERT = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 50),
};

/* CMD_ENABLE2 flags */
Expand Down
4 changes: 0 additions & 4 deletions trunk/drivers/net/enic/vnic_enet.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@
#ifndef _VNIC_ENIC_H_
#define _VNIC_ENIC_H_

/* Hardware intr coalesce timer is in units of 1.5us */
#define INTR_COALESCE_USEC_TO_HW(usec) ((usec) * 2/3)
#define INTR_COALESCE_HW_TO_USEC(usec) ((usec) * 3/2)

/* Device-specific region: enet configuration */
struct vnic_enet_config {
u32 flags;
Expand Down
7 changes: 4 additions & 3 deletions trunk/drivers/net/enic/vnic_intr.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ int vnic_intr_alloc(struct vnic_dev *vdev, struct vnic_intr *intr,
return 0;
}

void vnic_intr_init(struct vnic_intr *intr, unsigned int coalescing_timer,
void vnic_intr_init(struct vnic_intr *intr, u32 coalescing_timer,
unsigned int coalescing_type, unsigned int mask_on_assertion)
{
vnic_intr_coalescing_timer_set(intr, coalescing_timer);
Expand All @@ -56,9 +56,10 @@ void vnic_intr_init(struct vnic_intr *intr, unsigned int coalescing_timer,
}

void vnic_intr_coalescing_timer_set(struct vnic_intr *intr,
unsigned int coalescing_timer)
u32 coalescing_timer)
{
iowrite32(coalescing_timer, &intr->ctrl->coalescing_timer);
iowrite32(vnic_dev_intr_coal_timer_usec_to_hw(intr->vdev,
coalescing_timer), &intr->ctrl->coalescing_timer);
}

void vnic_intr_clean(struct vnic_intr *intr)
Expand Down
6 changes: 2 additions & 4 deletions trunk/drivers/net/enic/vnic_intr.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@

#include "vnic_dev.h"

#define VNIC_INTR_TIMER_MAX 0xffff

#define VNIC_INTR_TIMER_TYPE_ABS 0
#define VNIC_INTR_TIMER_TYPE_QUIET 1

Expand Down Expand Up @@ -104,10 +102,10 @@ static inline u32 vnic_intr_legacy_pba(u32 __iomem *legacy_pba)
void vnic_intr_free(struct vnic_intr *intr);
int vnic_intr_alloc(struct vnic_dev *vdev, struct vnic_intr *intr,
unsigned int index);
void vnic_intr_init(struct vnic_intr *intr, unsigned int coalescing_timer,
void vnic_intr_init(struct vnic_intr *intr, u32 coalescing_timer,
unsigned int coalescing_type, unsigned int mask_on_assertion);
void vnic_intr_coalescing_timer_set(struct vnic_intr *intr,
unsigned int coalescing_timer);
u32 coalescing_timer);
void vnic_intr_clean(struct vnic_intr *intr);

#endif /* _VNIC_INTR_H_ */

0 comments on commit a0a8151

Please sign in to comment.