static int vlan_dev_set_mac_address(struct net_device *dev, void *p) { struct net_device *real_dev = vlan_dev_info(dev)->real_dev; struct sockaddr *addr = p; int err; if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; if (!(dev->flags & IFF_UP)) goto out; if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) { err = dev_unicast_add(real_dev, addr->sa_data, ETH_ALEN); if (err < 0) return err; } if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) dev_unicast_delete(real_dev, dev->dev_addr, ETH_ALEN); out: memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); return 0; }
int vlan_dev_stop(struct net_device *dev) { struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; dev_mc_unsync(real_dev, dev); if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(real_dev, -1); if (dev->flags & IFF_PROMISC) dev_set_promiscuity(real_dev, -1); if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) dev_unicast_delete(real_dev, dev->dev_addr, dev->addr_len); return 0; }
static int vlan_dev_open(struct net_device *dev) { struct vlan_dev_info *vlan = vlan_dev_info(dev); struct net_device *real_dev = vlan->real_dev; int err; if (!(real_dev->flags & IFF_UP) && !(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) return -ENETDOWN; if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { err = dev_unicast_add(real_dev, dev->dev_addr); if (err < 0) goto out; } if (dev->flags & IFF_ALLMULTI) { err = dev_set_allmulti(real_dev, 1); if (err < 0) goto del_unicast; } if (dev->flags & IFF_PROMISC) { err = dev_set_promiscuity(real_dev, 1); if (err < 0) goto clear_allmulti; } memcpy(vlan->real_dev_addr, real_dev->dev_addr, ETH_ALEN); if (vlan->flags & VLAN_FLAG_GVRP) vlan_gvrp_request_join(dev); netif_carrier_on(dev); return 0; clear_allmulti: if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(real_dev, -1); del_unicast: if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) dev_unicast_delete(real_dev, dev->dev_addr); out: netif_carrier_off(dev); return err; }
static int vlan_dev_stop(struct net_device *dev) { struct vlan_dev_info *vlan = vlan_dev_info(dev); struct net_device *real_dev = vlan->real_dev; if (vlan->flags & VLAN_FLAG_GVRP) vlan_gvrp_request_leave(dev); dev_mc_unsync(real_dev, dev); dev_unicast_unsync(real_dev, dev); if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(real_dev, -1); if (dev->flags & IFF_PROMISC) dev_set_promiscuity(real_dev, -1); if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) dev_unicast_delete(real_dev, dev->dev_addr, dev->addr_len); return 0; }
/* * fcoe_sw_destroy - FCoE software HBA tear-down function * @netdev: ptr to the associated net_device * * Returns: 0 if link is OK for use by FCoE. */ static int fcoe_sw_destroy(struct net_device *netdev) { int cpu; struct fc_lport *lp = NULL; struct fcoe_softc *fc; u8 flogi_maddr[ETH_ALEN]; BUG_ON(!netdev); printk(KERN_DEBUG "fcoe_sw_destroy:interface on %s\n", netdev->name); lp = fcoe_hostlist_lookup(netdev); if (!lp) return -ENODEV; fc = fcoe_softc(lp); /* Logout of the fabric */ fc_fabric_logoff(lp); /* Remove the instance from fcoe's list */ fcoe_hostlist_remove(lp); /* Don't listen for Ethernet packets anymore */ dev_remove_pack(&fc->fcoe_packet_type); /* Cleanup the fc_lport */ fc_lport_destroy(lp); fc_fcp_destroy(lp); /* Detach from the scsi-ml */ fc_remove_host(lp->host); scsi_remove_host(lp->host); /* There are no more rports or I/O, free the EM */ if (lp->emp) fc_exch_mgr_free(lp->emp); /* Delete secondary MAC addresses */ rtnl_lock(); memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN); if (compare_ether_addr(fc->data_src_addr, (u8[6]) { 0 })) dev_unicast_delete(fc->real_dev, fc->data_src_addr, ETH_ALEN); rtnl_unlock(); /* Free the per-CPU revieve threads */ fcoe_percpu_clean(lp); /* Free existing skbs */ fcoe_clean_pending_queue(lp); /* Free memory used by statistical counters */ for_each_online_cpu(cpu) kfree(lp->dev_stats[cpu]); /* Release the net_device and Scsi_Host */ dev_put(fc->real_dev); scsi_host_put(lp->host); return 0; }