Files
@ d0a14f973771
Branch filter:
Location: vmkdrivers/vmkdrivers/src_9/drivers/net/tg3/tg3_vmware.c
d0a14f973771
4.4 KiB
text/x-csrc
ESXi-5.0-U1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | /* Copyright (C) 2010 Broadcom Corporation.
* Portions Copyright (C) VMware, Inc. 2007-2011. All Rights Reserved.
*/
static void tg3_vmware_timer(struct tg3 *tp)
{
/*
* If the driver says this NIC is in promiscuous mode, the hardware
* better agree with it. See PR 88299 for more details, but there
* are cases (eg. bcm5704 rev10) that the set promiscuous bit is
* lost for no reason and this seems to be the least intrusive
* workaround for that issue (likely a hardware bug).
*
* This is happening on other cards as well (BCM5700 rev04) PR 97750
* Also, on some cards (5703) we have seen other bits getting messed up
*/
if (netif_carrier_ok(tp->dev)) {
u32 rx_mode = tr32(MAC_RX_MODE);
if (!(rx_mode & RX_MODE_PROMISC) && (rx_mode != tp->rx_mode)) {
u32 val;
tg3_read_mem(tp, 0xc04, &val);
if (val != 1) {
netdev_info(tp->dev, "ASF has wrong host driver state (0x%x)\n",
val);
}
/*
* We love to warn the users every time there is such a
* register reset, but we do not want to do it forever
* given some NICs are really that bad (PR 105488).
*/
if (tp->vmware.rx_mode_reset_counter < 200) {
netdev_info(tp->dev, "%s: rx_mode "
"0x%x(%s)=>0x%x tg3_flags 0x%x "
"tg3_flags2 0x%x\n",
tp->dev->name, rx_mode,
rx_mode & RX_MODE_PROMISC ? "on" : "off",
tp->rx_mode, tp->tg3_flags,
tp->tg3_flags2);
tp->vmware.rx_mode_reset_counter++;
}
tw32_f(MAC_RX_MODE, tp->rx_mode);
}
}
/*
* we've seen ssome 5703's (rev 10) which don't seen to
* generate an interrupt on link-up state changes. bug 89197.
*/
if (!netif_carrier_ok(tp->dev) &&
!(tp->tg3_flags &
(TG3_FLAG_USE_LINKCHG_REG | TG3_FLAG_POLL_SERDES))) {
struct tg3_hw_status *sblk = tp->napi[0].hw_status;
if (sblk->status & SD_STATUS_LINK_CHG) {
sblk->status = SD_STATUS_UPDATED |
(sblk->status & ~SD_STATUS_LINK_CHG);
tg3_setup_phy(tp, 0);
}
}
}
#if !defined(TG3_VMWARE_BMAPILNX_DISABLE)
static int
tg3_vmware_ioctl_cim(struct net_device *dev, struct ifreq *ifr)
{
struct tg3 *tp = netdev_priv(dev);
void __user *useraddr = ifr->ifr_data;
struct tg3_ioctl_req req;
int rc = 0;
u32 val;
if (copy_from_user(&req, useraddr, sizeof(req))) {
netdev_err(dev, "%s: could not copy "
"from user tg3_ioctl_req\n", __func__);
return -EFAULT;
}
switch(req.cmd) {
case TG3_VMWARE_CIM_CMD_ENABLE_NIC:
netdev_info(dev, "%s: enable NIC\n", __func__);
rc = tg3_open(tp->dev);
break;
case TG3_VMWARE_CIM_CMD_DISABLE_NIC:
netdev_info(dev, "%s: disable NIC\n", __func__);
rc = tg3_close(tp->dev);
break;
case TG3_VMWARE_CIM_CMD_REG_READ: {
if(0x7ffc < req.cmd_req.reg_read.reg_offset) {
netdev_err(dev, "%s: reg read: "
"out of range: req reg: 0x%x\n",
__func__, req.cmd_req.reg_read.reg_offset);
rc = -EINVAL;
break;
}
val = tr32(req.cmd_req.reg_read.reg_offset);
netdev_info(dev, "%s: reg read: reg: 0x%x value:0x%x",
__func__, req.cmd_req.reg_read.reg_offset,
req.cmd_req.reg_read.reg_value);
req.cmd_req.reg_read.reg_value = val;
break;
} case TG3_VMWARE_CIM_CMD_REG_WRITE: {
if(0x7ffc < req.cmd_req.reg_write.reg_offset) {
netdev_err(dev, "%s: reg write: "
"out of range: req reg: 0x%x\n",
__func__, req.cmd_req.reg_write.reg_offset);
rc = -EINVAL;
break;
}
netdev_info(dev, "%s: reg write: reg: 0x%x value:0x%x",
__func__, req.cmd_req.reg_write.reg_offset,
req.cmd_req.reg_write.reg_value);
tw32(req.cmd_req.reg_write.reg_offset,
req.cmd_req.reg_write.reg_value);
break;
} case TG3_VMWARE_CIM_CMD_GET_NIC_PARAM:
netdev_info(dev, "%s: get NIC param\n", __func__);
req.cmd_req.get_nic_param.mtu = dev->mtu;
memcpy(req.cmd_req.get_nic_param.current_mac_addr,
dev->dev_addr,
sizeof(req.cmd_req.get_nic_param.current_mac_addr));
break;
case TG3_VMWARE_CIM_CMD_GET_NIC_STATUS:
netdev_info(dev, "%s: get NIC status\n", __func__);
req.cmd_req.get_nic_status.nic_status = netif_running(dev);
break;
default:
netdev_err(dev, "%s: unknown req.cmd: 0x%x\n",
__func__, req.cmd);
rc = -EINVAL;
}
if (rc == 0 &&
copy_to_user(useraddr, &req, sizeof(req))) {
netdev_err(dev, "%s: couldn't copy to user tg3_ioctl_req\n",
__func__);
return -EFAULT;
}
return rc;
}
#endif /* TG3_VMWARE_BMAPILNX */
|