1a6a5580cSJeff Kirsher /* 2a6a5580cSJeff Kirsher * Copyright 2011 Cisco Systems, Inc. All rights reserved. 3a6a5580cSJeff Kirsher * 4a6a5580cSJeff Kirsher * This program is free software; you may redistribute it and/or modify 5a6a5580cSJeff Kirsher * it under the terms of the GNU General Public License as published by 6a6a5580cSJeff Kirsher * the Free Software Foundation; version 2 of the License. 7a6a5580cSJeff Kirsher * 8a6a5580cSJeff Kirsher * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 9a6a5580cSJeff Kirsher * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 10a6a5580cSJeff Kirsher * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 11a6a5580cSJeff Kirsher * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 12a6a5580cSJeff Kirsher * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 13a6a5580cSJeff Kirsher * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14a6a5580cSJeff Kirsher * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 15a6a5580cSJeff Kirsher * SOFTWARE. 16a6a5580cSJeff Kirsher * 17a6a5580cSJeff Kirsher */ 18a6a5580cSJeff Kirsher 19a6a5580cSJeff Kirsher #include <linux/pci.h> 20a6a5580cSJeff Kirsher #include <linux/etherdevice.h> 21a6a5580cSJeff Kirsher 22a6a5580cSJeff Kirsher #include "vnic_dev.h" 23a6a5580cSJeff Kirsher #include "vnic_vic.h" 24a6a5580cSJeff Kirsher #include "enic_res.h" 25a6a5580cSJeff Kirsher #include "enic.h" 26a6a5580cSJeff Kirsher #include "enic_dev.h" 27a6a5580cSJeff Kirsher 28a6a5580cSJeff Kirsher int enic_dev_fw_info(struct enic *enic, struct vnic_devcmd_fw_info **fw_info) 29a6a5580cSJeff Kirsher { 30a6a5580cSJeff Kirsher int err; 31a6a5580cSJeff Kirsher 32a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 33a6a5580cSJeff Kirsher err = vnic_dev_fw_info(enic->vdev, fw_info); 34a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 35a6a5580cSJeff Kirsher 36a6a5580cSJeff Kirsher return err; 37a6a5580cSJeff Kirsher } 38a6a5580cSJeff Kirsher 39a6a5580cSJeff Kirsher int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats) 40a6a5580cSJeff Kirsher { 41a6a5580cSJeff Kirsher int err; 42a6a5580cSJeff Kirsher 43a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 44a6a5580cSJeff Kirsher err = vnic_dev_stats_dump(enic->vdev, vstats); 45a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 46a6a5580cSJeff Kirsher 47a6a5580cSJeff Kirsher return err; 48a6a5580cSJeff Kirsher } 49a6a5580cSJeff Kirsher 50a6a5580cSJeff Kirsher int enic_dev_add_station_addr(struct enic *enic) 51a6a5580cSJeff Kirsher { 52a6a5580cSJeff Kirsher int err; 53a6a5580cSJeff Kirsher 54a6a5580cSJeff Kirsher if (!is_valid_ether_addr(enic->netdev->dev_addr)) 55a6a5580cSJeff Kirsher return -EADDRNOTAVAIL; 56a6a5580cSJeff Kirsher 57a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 58a6a5580cSJeff Kirsher err = vnic_dev_add_addr(enic->vdev, enic->netdev->dev_addr); 59a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 60a6a5580cSJeff Kirsher 61a6a5580cSJeff Kirsher return err; 62a6a5580cSJeff Kirsher } 63a6a5580cSJeff Kirsher 64a6a5580cSJeff Kirsher int enic_dev_del_station_addr(struct enic *enic) 65a6a5580cSJeff Kirsher { 66a6a5580cSJeff Kirsher int err; 67a6a5580cSJeff Kirsher 68a6a5580cSJeff Kirsher if (!is_valid_ether_addr(enic->netdev->dev_addr)) 69a6a5580cSJeff Kirsher return -EADDRNOTAVAIL; 70a6a5580cSJeff Kirsher 71a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 72a6a5580cSJeff Kirsher err = vnic_dev_del_addr(enic->vdev, enic->netdev->dev_addr); 73a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 74a6a5580cSJeff Kirsher 75a6a5580cSJeff Kirsher return err; 76a6a5580cSJeff Kirsher } 77a6a5580cSJeff Kirsher 78a6a5580cSJeff Kirsher int enic_dev_packet_filter(struct enic *enic, int directed, int multicast, 79a6a5580cSJeff Kirsher int broadcast, int promisc, int allmulti) 80a6a5580cSJeff Kirsher { 81a6a5580cSJeff Kirsher int err; 82a6a5580cSJeff Kirsher 83a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 84a6a5580cSJeff Kirsher err = vnic_dev_packet_filter(enic->vdev, directed, 85a6a5580cSJeff Kirsher multicast, broadcast, promisc, allmulti); 86a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 87a6a5580cSJeff Kirsher 88a6a5580cSJeff Kirsher return err; 89a6a5580cSJeff Kirsher } 90a6a5580cSJeff Kirsher 91a6a5580cSJeff Kirsher int enic_dev_add_addr(struct enic *enic, u8 *addr) 92a6a5580cSJeff Kirsher { 93a6a5580cSJeff Kirsher int err; 94a6a5580cSJeff Kirsher 95a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 96a6a5580cSJeff Kirsher err = vnic_dev_add_addr(enic->vdev, addr); 97a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 98a6a5580cSJeff Kirsher 99a6a5580cSJeff Kirsher return err; 100a6a5580cSJeff Kirsher } 101a6a5580cSJeff Kirsher 102a6a5580cSJeff Kirsher int enic_dev_del_addr(struct enic *enic, u8 *addr) 103a6a5580cSJeff Kirsher { 104a6a5580cSJeff Kirsher int err; 105a6a5580cSJeff Kirsher 106a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 107a6a5580cSJeff Kirsher err = vnic_dev_del_addr(enic->vdev, addr); 108a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 109a6a5580cSJeff Kirsher 110a6a5580cSJeff Kirsher return err; 111a6a5580cSJeff Kirsher } 112a6a5580cSJeff Kirsher 113a6a5580cSJeff Kirsher int enic_dev_notify_unset(struct enic *enic) 114a6a5580cSJeff Kirsher { 115a6a5580cSJeff Kirsher int err; 116a6a5580cSJeff Kirsher 117a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 118a6a5580cSJeff Kirsher err = vnic_dev_notify_unset(enic->vdev); 119a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 120a6a5580cSJeff Kirsher 121a6a5580cSJeff Kirsher return err; 122a6a5580cSJeff Kirsher } 123a6a5580cSJeff Kirsher 124a6a5580cSJeff Kirsher int enic_dev_hang_notify(struct enic *enic) 125a6a5580cSJeff Kirsher { 126a6a5580cSJeff Kirsher int err; 127a6a5580cSJeff Kirsher 128a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 129a6a5580cSJeff Kirsher err = vnic_dev_hang_notify(enic->vdev); 130a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 131a6a5580cSJeff Kirsher 132a6a5580cSJeff Kirsher return err; 133a6a5580cSJeff Kirsher } 134a6a5580cSJeff Kirsher 135a6a5580cSJeff Kirsher int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic) 136a6a5580cSJeff Kirsher { 137a6a5580cSJeff Kirsher int err; 138a6a5580cSJeff Kirsher 139a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 140a6a5580cSJeff Kirsher err = vnic_dev_set_ig_vlan_rewrite_mode(enic->vdev, 141a6a5580cSJeff Kirsher IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN); 142a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 143a6a5580cSJeff Kirsher 144a6a5580cSJeff Kirsher return err; 145a6a5580cSJeff Kirsher } 146a6a5580cSJeff Kirsher 147a6a5580cSJeff Kirsher int enic_dev_enable(struct enic *enic) 148a6a5580cSJeff Kirsher { 149a6a5580cSJeff Kirsher int err; 150a6a5580cSJeff Kirsher 151a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 152a6a5580cSJeff Kirsher err = vnic_dev_enable_wait(enic->vdev); 153a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 154a6a5580cSJeff Kirsher 155a6a5580cSJeff Kirsher return err; 156a6a5580cSJeff Kirsher } 157a6a5580cSJeff Kirsher 158a6a5580cSJeff Kirsher int enic_dev_disable(struct enic *enic) 159a6a5580cSJeff Kirsher { 160a6a5580cSJeff Kirsher int err; 161a6a5580cSJeff Kirsher 162a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 163a6a5580cSJeff Kirsher err = vnic_dev_disable(enic->vdev); 164a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 165a6a5580cSJeff Kirsher 166a6a5580cSJeff Kirsher return err; 167a6a5580cSJeff Kirsher } 168a6a5580cSJeff Kirsher 169a6a5580cSJeff Kirsher int enic_dev_intr_coal_timer_info(struct enic *enic) 170a6a5580cSJeff Kirsher { 171a6a5580cSJeff Kirsher int err; 172a6a5580cSJeff Kirsher 173a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 174a6a5580cSJeff Kirsher err = vnic_dev_intr_coal_timer_info(enic->vdev); 175a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 176a6a5580cSJeff Kirsher 177a6a5580cSJeff Kirsher return err; 178a6a5580cSJeff Kirsher } 179a6a5580cSJeff Kirsher 180a6a5580cSJeff Kirsher int enic_vnic_dev_deinit(struct enic *enic) 181a6a5580cSJeff Kirsher { 182a6a5580cSJeff Kirsher int err; 183a6a5580cSJeff Kirsher 184a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 185a6a5580cSJeff Kirsher err = vnic_dev_deinit(enic->vdev); 186a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 187a6a5580cSJeff Kirsher 188a6a5580cSJeff Kirsher return err; 189a6a5580cSJeff Kirsher } 190a6a5580cSJeff Kirsher 191a6a5580cSJeff Kirsher int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp) 192a6a5580cSJeff Kirsher { 193a6a5580cSJeff Kirsher int err; 194a6a5580cSJeff Kirsher 195a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 196a6a5580cSJeff Kirsher err = vnic_dev_init_prov2(enic->vdev, 197a6a5580cSJeff Kirsher (u8 *)vp, vic_provinfo_size(vp)); 198a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 199a6a5580cSJeff Kirsher 200a6a5580cSJeff Kirsher return err; 201a6a5580cSJeff Kirsher } 202a6a5580cSJeff Kirsher 203a6a5580cSJeff Kirsher int enic_dev_deinit_done(struct enic *enic, int *status) 204a6a5580cSJeff Kirsher { 205a6a5580cSJeff Kirsher int err; 206a6a5580cSJeff Kirsher 207a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 208a6a5580cSJeff Kirsher err = vnic_dev_deinit_done(enic->vdev, status); 209a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 210a6a5580cSJeff Kirsher 211a6a5580cSJeff Kirsher return err; 212a6a5580cSJeff Kirsher } 213a6a5580cSJeff Kirsher 214a6a5580cSJeff Kirsher /* rtnl lock is held */ 215a6a5580cSJeff Kirsher void enic_vlan_rx_add_vid(struct net_device *netdev, u16 vid) 216a6a5580cSJeff Kirsher { 217a6a5580cSJeff Kirsher struct enic *enic = netdev_priv(netdev); 218a6a5580cSJeff Kirsher 219a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 220a6a5580cSJeff Kirsher enic_add_vlan(enic, vid); 221a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 222a6a5580cSJeff Kirsher } 223a6a5580cSJeff Kirsher 224a6a5580cSJeff Kirsher /* rtnl lock is held */ 225a6a5580cSJeff Kirsher void enic_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) 226a6a5580cSJeff Kirsher { 227a6a5580cSJeff Kirsher struct enic *enic = netdev_priv(netdev); 228a6a5580cSJeff Kirsher 229a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 230a6a5580cSJeff Kirsher enic_del_vlan(enic, vid); 231a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 232a6a5580cSJeff Kirsher } 233a6a5580cSJeff Kirsher 234a6a5580cSJeff Kirsher int enic_dev_enable2(struct enic *enic, int active) 235a6a5580cSJeff Kirsher { 236a6a5580cSJeff Kirsher int err; 237a6a5580cSJeff Kirsher 238a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 239a6a5580cSJeff Kirsher err = vnic_dev_enable2(enic->vdev, active); 240a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 241a6a5580cSJeff Kirsher 242a6a5580cSJeff Kirsher return err; 243a6a5580cSJeff Kirsher } 244a6a5580cSJeff Kirsher 245a6a5580cSJeff Kirsher int enic_dev_enable2_done(struct enic *enic, int *status) 246a6a5580cSJeff Kirsher { 247a6a5580cSJeff Kirsher int err; 248a6a5580cSJeff Kirsher 249a6a5580cSJeff Kirsher spin_lock(&enic->devcmd_lock); 250a6a5580cSJeff Kirsher err = vnic_dev_enable2_done(enic->vdev, status); 251a6a5580cSJeff Kirsher spin_unlock(&enic->devcmd_lock); 252a6a5580cSJeff Kirsher 253a6a5580cSJeff Kirsher return err; 254a6a5580cSJeff Kirsher } 255a6a5580cSJeff Kirsher 256a6a5580cSJeff Kirsher int enic_dev_status_to_errno(int devcmd_status) 257a6a5580cSJeff Kirsher { 258a6a5580cSJeff Kirsher switch (devcmd_status) { 259a6a5580cSJeff Kirsher case ERR_SUCCESS: 260a6a5580cSJeff Kirsher return 0; 261a6a5580cSJeff Kirsher case ERR_EINVAL: 262a6a5580cSJeff Kirsher return -EINVAL; 263a6a5580cSJeff Kirsher case ERR_EFAULT: 264a6a5580cSJeff Kirsher return -EFAULT; 265a6a5580cSJeff Kirsher case ERR_EPERM: 266a6a5580cSJeff Kirsher return -EPERM; 267a6a5580cSJeff Kirsher case ERR_EBUSY: 268a6a5580cSJeff Kirsher return -EBUSY; 269a6a5580cSJeff Kirsher case ERR_ECMDUNKNOWN: 270a6a5580cSJeff Kirsher case ERR_ENOTSUPPORTED: 271a6a5580cSJeff Kirsher return -EOPNOTSUPP; 272a6a5580cSJeff Kirsher case ERR_EBADSTATE: 273a6a5580cSJeff Kirsher return -EINVAL; 274a6a5580cSJeff Kirsher case ERR_ENOMEM: 275a6a5580cSJeff Kirsher return -ENOMEM; 276a6a5580cSJeff Kirsher case ERR_ETIMEDOUT: 277a6a5580cSJeff Kirsher return -ETIMEDOUT; 278a6a5580cSJeff Kirsher case ERR_ELINKDOWN: 279a6a5580cSJeff Kirsher return -ENETDOWN; 280a6a5580cSJeff Kirsher case ERR_EINPROGRESS: 281a6a5580cSJeff Kirsher return -EINPROGRESS; 282a6a5580cSJeff Kirsher case ERR_EMAXRES: 283a6a5580cSJeff Kirsher default: 284a6a5580cSJeff Kirsher return (devcmd_status < 0) ? devcmd_status : -1; 285a6a5580cSJeff Kirsher } 286a6a5580cSJeff Kirsher } 287