diff options
Diffstat (limited to 'drivers/net/ethernet/cisco/enic')
-rw-r--r-- | drivers/net/ethernet/cisco/enic/enic.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/enic_main.c | 52 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/enic_pp.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/enic_res.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/vnic_dev.c | 76 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/vnic_dev.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/vnic_devcmd.h | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/vnic_rq.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/vnic_wq.c | 4 |
9 files changed, 98 insertions, 62 deletions
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h index c52295cd05ef..afe9b1662b8c 100644 --- a/drivers/net/ethernet/cisco/enic/enic.h +++ b/drivers/net/ethernet/cisco/enic/enic.h @@ -32,13 +32,13 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.31" +#define DRV_VERSION "2.1.1.39" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 #define ENIC_WQ_MAX 1 -#define ENIC_RQ_MAX 1 +#define ENIC_RQ_MAX 8 #define ENIC_CQ_MAX (ENIC_WQ_MAX + ENIC_RQ_MAX) #define ENIC_INTR_MAX (ENIC_CQ_MAX + 2) diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 0e4edd3b6bee..77b4e873f91c 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -865,6 +865,7 @@ static int enic_set_mac_addr(struct net_device *netdev, char *addr) } memcpy(netdev->dev_addr, addr, netdev->addr_len); + netdev->addr_assign_type &= ~NET_ADDR_RANDOM; return 0; } @@ -1068,9 +1069,18 @@ static int enic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) if (err) return err; - if (is_valid_ether_addr(mac)) { - memcpy(pp->vf_mac, mac, ETH_ALEN); - return 0; + if (is_valid_ether_addr(mac) || is_zero_ether_addr(mac)) { + if (vf == PORT_SELF_VF) { + memcpy(pp->vf_mac, mac, ETH_ALEN); + return 0; + } else { + /* + * For sriov vf's set the mac in hw + */ + ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, + vnic_dev_set_mac_addr, mac); + return enic_dev_status_to_errno(err); + } } else return -EINVAL; } @@ -1114,12 +1124,23 @@ static int enic_set_vf_port(struct net_device *netdev, int vf, nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX); } - /* Special case handling: mac came from IFLA_VF_MAC */ - if (!is_zero_ether_addr(prev_pp.vf_mac)) - memcpy(pp->mac_addr, prev_pp.vf_mac, ETH_ALEN); + if (vf == PORT_SELF_VF) { + /* Special case handling: mac came from IFLA_VF_MAC */ + if (!is_zero_ether_addr(prev_pp.vf_mac)) + memcpy(pp->mac_addr, prev_pp.vf_mac, ETH_ALEN); - if (vf == PORT_SELF_VF && is_zero_ether_addr(netdev->dev_addr)) - random_ether_addr(netdev->dev_addr); + if (is_zero_ether_addr(netdev->dev_addr)) + eth_hw_addr_random(netdev); + } else { + /* SR-IOV VF: get mac from adapter */ + ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, + vnic_dev_get_mac_addr, pp->mac_addr); + if (err) { + netdev_err(netdev, "Error getting mac for vf %d\n", vf); + memcpy(pp, &prev_pp, sizeof(*pp)); + return enic_dev_status_to_errno(err); + } + } err = enic_process_set_pp_request(enic, vf, &prev_pp, &restore_pp); if (err) { @@ -1147,7 +1168,8 @@ static int enic_set_vf_port(struct net_device *netdev, int vf, } } - memset(pp->vf_mac, 0, ETH_ALEN); + if (vf == PORT_SELF_VF) + memset(pp->vf_mac, 0, ETH_ALEN); return err; } @@ -2280,10 +2302,8 @@ static int __devinit enic_probe(struct pci_dev *pdev, */ netdev = alloc_etherdev(sizeof(struct enic)); - if (!netdev) { - pr_err("Etherdev alloc failed, aborting\n"); + if (!netdev) return -ENOMEM; - } pci_set_drvdata(pdev, netdev); @@ -2388,7 +2408,6 @@ static int __devinit enic_probe(struct pci_dev *pdev, /* Allocate structure for port profiles */ enic->pp = kcalloc(num_pps, sizeof(*enic->pp), GFP_KERNEL); if (!enic->pp) { - pr_err("port profile alloc failed, aborting\n"); err = -ENOMEM; goto err_out_disable_sriov_pp; } @@ -2433,7 +2452,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, * called later by an upper layer. */ - if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic)) { + if (!enic_is_dynamic(enic)) { err = vnic_dev_init(enic->vdev, 0); if (err) { dev_err(dev, "vNIC dev init failed, aborting\n"); @@ -2466,11 +2485,6 @@ static int __devinit enic_probe(struct pci_dev *pdev, enic->port_mtu = enic->config.mtu; (void)enic_change_mtu(netdev, enic->port_mtu); -#ifdef CONFIG_PCI_IOV - if (enic_is_sriov_vf(enic) && is_zero_ether_addr(enic->mac_addr)) - random_ether_addr(enic->mac_addr); -#endif - err = enic_set_mac_addr(netdev, enic->mac_addr); if (err) { dev_err(dev, "Invalid MAC address, aborting\n"); diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.c b/drivers/net/ethernet/cisco/enic/enic_pp.c index c347b6236f8f..dafea1ecb7b1 100644 --- a/drivers/net/ethernet/cisco/enic/enic_pp.c +++ b/drivers/net/ethernet/cisco/enic/enic_pp.c @@ -207,7 +207,7 @@ static int enic_pp_disassociate(struct enic *enic, int vf, if (!is_zero_ether_addr(pp->mac_addr)) ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_del_addr, pp->mac_addr); - else if (!is_zero_ether_addr(netdev->dev_addr)) + else if (vf == PORT_SELF_VF && !is_zero_ether_addr(netdev->dev_addr)) ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_del_addr, netdev->dev_addr); @@ -294,7 +294,7 @@ static int enic_pp_associate(struct enic *enic, int vf, if (!is_zero_ether_addr(pp->mac_addr)) ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_add_addr, pp->mac_addr); - else if (!is_zero_ether_addr(netdev->dev_addr)) + else if (vf == PORT_SELF_VF && !is_zero_ether_addr(netdev->dev_addr)) ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_add_addr, netdev->dev_addr); diff --git a/drivers/net/ethernet/cisco/enic/enic_res.c b/drivers/net/ethernet/cisco/enic/enic_res.c index 4a35367de790..31d658880c3c 100644 --- a/drivers/net/ethernet/cisco/enic/enic_res.c +++ b/drivers/net/ethernet/cisco/enic/enic_res.c @@ -44,7 +44,7 @@ int enic_get_vnic_config(struct enic *enic) struct vnic_enet_config *c = &enic->config; int err; - err = vnic_dev_mac_addr(enic->vdev, enic->mac_addr); + err = vnic_dev_get_mac_addr(enic->vdev, enic->mac_addr); if (err) { dev_err(enic_get_dev(enic), "Error getting MAC addr, %d\n", err); diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.c b/drivers/net/ethernet/cisco/enic/vnic_dev.c index 31e7f9bc2067..605b22283be1 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_dev.c +++ b/drivers/net/ethernet/cisco/enic/vnic_dev.c @@ -439,11 +439,12 @@ int vnic_dev_fw_info(struct vnic_dev *vdev, a1 = sizeof(struct vnic_devcmd_fw_info); /* only get fw_info once and cache it */ - err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO, &a0, &a1, wait); - if (err == ERR_ECMDUNKNOWN) { + if (vnic_dev_capable(vdev, CMD_MCPU_FW_INFO)) + err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO, + &a0, &a1, wait); + else err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO_OLD, &a0, &a1, wait); - } } *fw_info = vdev->fw_info; @@ -504,13 +505,11 @@ int vnic_dev_enable_wait(struct vnic_dev *vdev) { u64 a0 = 0, a1 = 0; int wait = 1000; - int err; - err = vnic_dev_cmd(vdev, CMD_ENABLE_WAIT, &a0, &a1, wait); - if (err == ERR_ECMDUNKNOWN) + if (vnic_dev_capable(vdev, CMD_ENABLE_WAIT)) + return vnic_dev_cmd(vdev, CMD_ENABLE_WAIT, &a0, &a1, wait); + else return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait); - - return err; } int vnic_dev_disable(struct vnic_dev *vdev) @@ -574,16 +573,15 @@ int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg) int wait = 1000; int err; - err = vnic_dev_cmd(vdev, CMD_HANG_RESET, &a0, &a1, wait); - if (err == ERR_ECMDUNKNOWN) { + if (vnic_dev_capable(vdev, CMD_HANG_RESET)) { + return vnic_dev_cmd(vdev, CMD_HANG_RESET, + &a0, &a1, wait); + } else { err = vnic_dev_soft_reset(vdev, arg); if (err) return err; - return vnic_dev_init(vdev, 0); } - - return err; } int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done) @@ -594,11 +592,13 @@ int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done) *done = 0; - err = vnic_dev_cmd(vdev, CMD_HANG_RESET_STATUS, &a0, &a1, wait); - if (err) { - if (err == ERR_ECMDUNKNOWN) - return vnic_dev_soft_reset_done(vdev, done); - return err; + if (vnic_dev_capable(vdev, CMD_HANG_RESET_STATUS)) { + err = vnic_dev_cmd(vdev, CMD_HANG_RESET_STATUS, + &a0, &a1, wait); + if (err) + return err; + } else { + return vnic_dev_soft_reset_done(vdev, done); } *done = (a0 == 0); @@ -613,7 +613,7 @@ int vnic_dev_hang_notify(struct vnic_dev *vdev) return vnic_dev_cmd(vdev, CMD_HANG_NOTIFY, &a0, &a1, wait); } -int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr) +int vnic_dev_get_mac_addr(struct vnic_dev *vdev, u8 *mac_addr) { u64 a0, a1; int wait = 1000; @@ -622,7 +622,7 @@ int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr) for (i = 0; i < ETH_ALEN; i++) mac_addr[i] = 0; - err = vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait); + err = vnic_dev_cmd(vdev, CMD_GET_MAC_ADDR, &a0, &a1, wait); if (err) return err; @@ -691,13 +691,12 @@ int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev, { u64 a0 = ig_vlan_rewrite_mode, a1 = 0; int wait = 1000; - int err; - err = vnic_dev_cmd(vdev, CMD_IG_VLAN_REWRITE_MODE, &a0, &a1, wait); - if (err == ERR_ECMDUNKNOWN) + if (vnic_dev_capable(vdev, CMD_IG_VLAN_REWRITE_MODE)) + return vnic_dev_cmd(vdev, CMD_IG_VLAN_REWRITE_MODE, + &a0, &a1, wait); + else return 0; - - return err; } static int vnic_dev_notify_setcmd(struct vnic_dev *vdev, @@ -804,7 +803,7 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg) /* Emulate these for old CMD_INIT_v1 which * didn't pass a0 so no CMD_INITF_*. */ - vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait); + vnic_dev_cmd(vdev, CMD_GET_MAC_ADDR, &a0, &a1, wait); vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait); } } @@ -835,7 +834,10 @@ int vnic_dev_intr_coal_timer_info(struct vnic_dev *vdev) memset(vdev->args, 0, sizeof(vdev->args)); - err = _vnic_dev_cmd(vdev, CMD_INTR_COAL_CONVERT, wait); + if (vnic_dev_capable(vdev, CMD_INTR_COAL_CONVERT)) + err = _vnic_dev_cmd(vdev, CMD_INTR_COAL_CONVERT, wait); + else + err = ERR_ECMDUNKNOWN; /* Use defaults when firmware doesn't support the devcmd at all or * supports it for only specific hardware @@ -848,9 +850,11 @@ int vnic_dev_intr_coal_timer_info(struct vnic_dev *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]; + if (!err) { + 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; } @@ -1019,3 +1023,15 @@ int vnic_dev_deinit_done(struct vnic_dev *vdev, int *status) { return vnic_dev_cmd_status(vdev, CMD_DEINIT, status); } + +int vnic_dev_set_mac_addr(struct vnic_dev *vdev, u8 *mac_addr) +{ + u64 a0, a1; + int wait = 1000; + int i; + + for (i = 0; i < ETH_ALEN; i++) + ((u8 *)&a0)[i] = mac_addr[i]; + + return vnic_dev_cmd(vdev, CMD_SET_MAC_ADDR, &a0, &a1, wait); +} diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.h b/drivers/net/ethernet/cisco/enic/vnic_dev.h index 6a138b625d13..f3d9b79ba77e 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_dev.h +++ b/drivers/net/ethernet/cisco/enic/vnic_dev.h @@ -97,7 +97,7 @@ int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, int broadcast, int promisc, int allmulti); int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr); int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr); -int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr); +int vnic_dev_get_mac_addr(struct vnic_dev *vdev, u8 *mac_addr); int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr); int vnic_dev_notify_unset(struct vnic_dev *vdev); int vnic_dev_link_status(struct vnic_dev *vdev); @@ -131,5 +131,6 @@ int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len); int vnic_dev_enable2(struct vnic_dev *vdev, int active); int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status); int vnic_dev_deinit_done(struct vnic_dev *vdev, int *status); +int vnic_dev_set_mac_addr(struct vnic_dev *vdev, u8 *mac_addr); #endif /* _VNIC_DEV_H_ */ diff --git a/drivers/net/ethernet/cisco/enic/vnic_devcmd.h b/drivers/net/ethernet/cisco/enic/vnic_devcmd.h index 8025e8808d61..23d555255cf8 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_devcmd.h +++ b/drivers/net/ethernet/cisco/enic/vnic_devcmd.h @@ -131,7 +131,7 @@ enum vnic_devcmd_cmd { CMD_HANG_NOTIFY = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 8), /* MAC address in (u48)a0 */ - CMD_MAC_ADDR = _CMDC(_CMD_DIR_READ, + CMD_GET_MAC_ADDR = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ENET | _CMD_VTYPE_FC, 9), /* add addr from (u48)a0 */ @@ -337,6 +337,15 @@ enum vnic_devcmd_cmd { * (u32)a2 = maximum timer value in usec */ CMD_INTR_COAL_CONVERT = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 50), + + /* + * cmd_set_mac_addr + * set mac address + * in: + * (u48)a0 = mac addr + * + */ + CMD_SET_MAC_ADDR = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 55), }; /* CMD_ENABLE2 flags */ diff --git a/drivers/net/ethernet/cisco/enic/vnic_rq.c b/drivers/net/ethernet/cisco/enic/vnic_rq.c index 34105e0951a5..7e1488fc8ab2 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_rq.c +++ b/drivers/net/ethernet/cisco/enic/vnic_rq.c @@ -38,10 +38,8 @@ static int vnic_rq_alloc_bufs(struct vnic_rq *rq) for (i = 0; i < blks; i++) { rq->bufs[i] = kzalloc(VNIC_RQ_BUF_BLK_SZ(count), GFP_ATOMIC); - if (!rq->bufs[i]) { - pr_err("Failed to alloc rq_bufs\n"); + if (!rq->bufs[i]) return -ENOMEM; - } } for (i = 0; i < blks; i++) { diff --git a/drivers/net/ethernet/cisco/enic/vnic_wq.c b/drivers/net/ethernet/cisco/enic/vnic_wq.c index df61bd932ea6..5e0d7a2be9bc 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_wq.c +++ b/drivers/net/ethernet/cisco/enic/vnic_wq.c @@ -38,10 +38,8 @@ static int vnic_wq_alloc_bufs(struct vnic_wq *wq) for (i = 0; i < blks; i++) { wq->bufs[i] = kzalloc(VNIC_WQ_BUF_BLK_SZ(count), GFP_ATOMIC); - if (!wq->bufs[i]) { - pr_err("Failed to alloc wq_bufs\n"); + if (!wq->bufs[i]) return -ENOMEM; - } } for (i = 0; i < blks; i++) { |