int zd_mac_set_mac_address(struct net_device *netdev, void *p) { int r; unsigned long flags; struct sockaddr *addr = p; struct zd_mac *mac = zd_netdev_mac(netdev); struct zd_chip *chip = &mac->chip; if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; dev_dbg_f(zd_mac_dev(mac), "Setting MAC to " MAC_FMT "\n", MAC_ARG(addr->sa_data)); r = zd_write_mac_addr(chip, addr->sa_data); if (r) return r; spin_lock_irqsave(&mac->lock, flags); memcpy(netdev->dev_addr, addr->sa_data, ETH_ALEN); spin_unlock_irqrestore(&mac->lock, flags); return 0; }
static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u32 changed) { struct rtl8180_priv *priv = dev->priv; int i; if (changed & BSS_CHANGED_BSSID) { for (i = 0; i < ETH_ALEN; i++) rtl818x_iowrite8(priv, &priv->map->BSSID[i], info->bssid[i]); if (is_valid_ether_addr(info->bssid)) rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_INFRA); else rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_NO_LINK); } if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp) priv->rf->conf_erp(dev, info); }
static int art_read_mac(struct device_d *dev, const char *file) { int fd, rbytes; struct ar9300_eeprom eeprom; fd = open_and_lseek(file, O_RDONLY, AR93000_EPPROM_OFFSET); if (fd < 0) { dev_err(dev, "Failed to open eeprom path %s %d\n", file, fd); return fd; } rbytes = read_full(fd, &eeprom, sizeof(eeprom)); close(fd); if (rbytes < sizeof(eeprom)) { dev_err(dev, "Failed to read %s\n", file); return rbytes < 0 ? rbytes : -EIO; } dev_dbg(dev, "ART version: %x.%x\n", eeprom.eeprom_version, eeprom.template_version); dev_dbg(dev, "mac: %02x:%02x:%02x:%02x:%02x:%02x\n", eeprom.mac_addr[0], eeprom.mac_addr[1], eeprom.mac_addr[2], eeprom.mac_addr[3], eeprom.mac_addr[4], eeprom.mac_addr[5]); if (!is_valid_ether_addr(&eeprom.mac_addr[0])) { dev_err(dev, "bad MAC addr\n"); return -EILSEQ; } return art_set_mac(dev, &eeprom); }
static int vlan_validate(struct nlattr *tb[], struct nlattr *data[]) { struct ifla_vlan_flags *flags; u16 id; int err; if (tb[IFLA_ADDRESS]) { if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) return -EINVAL; if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) return -EADDRNOTAVAIL; } if (!data) return -EINVAL; if (data[IFLA_VLAN_ID]) { id = nla_get_u16(data[IFLA_VLAN_ID]); if (id >= VLAN_VID_MASK) return -ERANGE; } if (data[IFLA_VLAN_FLAGS]) { flags = nla_data(data[IFLA_VLAN_FLAGS]); if ((flags->flags & flags->mask) & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP)) return -EINVAL; } err = vlan_validate_qos_map(data[IFLA_VLAN_INGRESS_QOS]); if (err < 0) return err; err = vlan_validate_qos_map(data[IFLA_VLAN_EGRESS_QOS]); if (err < 0) return err; return 0; }
int br_add_if(struct net_bridge *br, struct net_device *dev) { struct net_bridge_port *p; if (dev->br_port != NULL) return -EBUSY; #if 0 if (dev->flags & IFF_LOOPBACK || dev->type != ARPHRD_ETHER) return -EINVAL; #endif if (dev->hard_start_xmit == br_dev_xmit) return -ELOOP; if (!is_valid_ether_addr(dev->dev_addr)) return -EADDRNOTAVAIL; dev_hold(dev); write_lock_bh(&br->lock); if ((p = new_nbp(br, dev)) == NULL) { write_unlock_bh(&br->lock); dev_put(dev); return -EXFULL; } dev_set_promiscuity(dev, 1); br_stp_recalculate_bridge_id(br); br_fdb_insert(br, p, dev->dev_addr, 1); if ((br->dev.flags & IFF_UP) && (dev->flags & IFF_UP)) br_stp_enable_port(p); write_unlock_bh(&br->lock); return 0; }
static int ks8842_set_mac(struct net_device *netdev, void *p) { struct ks8842_adapter *adapter = netdev_priv(netdev); unsigned long flags; struct sockaddr *addr = p; char *mac = (u8 *)addr->sa_data; int i; dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__); if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; memcpy(netdev->dev_addr, mac, netdev->addr_len); spin_lock_irqsave(&adapter->lock, flags); for (i = 0; i < ETH_ALEN; i++) { ks8842_write8(adapter, 2, mac[ETH_ALEN - i - 1], REG_MARL + i); ks8842_write8(adapter, 39, mac[ETH_ALEN - i - 1], REG_MACAR1 + i); } spin_unlock_irqrestore(&adapter->lock, flags); return 0; }
int board_eth_init(bd_t *bis) { int rv, n = 0; #ifdef CONFIG_DRIVER_TI_CPSW uint8_t mac_addr[6]; uint32_t mac_hi, mac_lo; if (!eth_getenv_enetaddr("ethaddr", mac_addr)) { printf("<ethaddr> not set. Reading from E-fuse\n"); /* try reading mac address from efuse */ mac_lo = readl(&cdev->macid0l); mac_hi = readl(&cdev->macid0h); mac_addr[0] = mac_hi & 0xFF; mac_addr[1] = (mac_hi & 0xFF00) >> 8; mac_addr[2] = (mac_hi & 0xFF0000) >> 16; mac_addr[3] = (mac_hi & 0xFF000000) >> 24; mac_addr[4] = mac_lo & 0xFF; mac_addr[5] = (mac_lo & 0xFF00) >> 8; if (is_valid_ether_addr(mac_addr)) eth_setenv_enetaddr("ethaddr", mac_addr); else goto try_usbether; }
static int rt2400pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) { struct eeprom_93cx6 eeprom; u32 reg; u16 word; u8 *mac; rt2x00pci_register_read(rt2x00dev, CSR21, ®); eeprom.data = rt2x00dev; eeprom.register_read = rt2400pci_eepromregister_read; eeprom.register_write = rt2400pci_eepromregister_write; eeprom.width = rt2x00_get_field32(reg, CSR21_TYPE_93C46) ? PCI_EEPROM_WIDTH_93C46 : PCI_EEPROM_WIDTH_93C66; eeprom.reg_data_in = 0; eeprom.reg_data_out = 0; eeprom.reg_data_clock = 0; eeprom.reg_chip_select = 0; eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom, EEPROM_SIZE / sizeof(u16)); mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { random_ether_addr(mac); EEPROM(rt2x00dev, "MAC: %pM\n", mac); } rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); if (word == 0xffff) { ERROR(rt2x00dev, "Invalid EEPROM data detected.\n"); return -EINVAL; } return 0; }
int mac_read_from_eeprom(void) { const u8 *mac; const char *mac_txt; if (read_eeprom()) { printf("I2C EEPROM read failed.\n"); return -1; } if (!eeprom_is_valid) { printf("I2C EEPROM content not valid\n"); return -1; } mac = NULL; switch (eeprom_version) { case 1: case 2: mac = (const u8 *)&eeprom_content.macaddress; break; } if (mac && is_valid_ether_addr(mac)) { eth_setenv_enetaddr("ethaddr", mac); if (mac_diag) { mac_txt = getenv("ethaddr"); if (mac_txt) printf("DIAG: MAC value [%s]\n", mac_txt); else printf("DIAG: failed to setup MAC env\n"); } } return 0; }
int igb_vmdq_open(struct net_device *dev) { struct igb_vmdq_adapter *vadapter = netdev_priv(dev); struct igb_adapter *adapter = vadapter->real_adapter; struct net_device *main_netdev = adapter->netdev; int hw_queue = vadapter->rx_ring->queue_index + adapter->vfs_allocated_count; if (test_bit(__IGB_DOWN, &adapter->state)) { DPRINTK(DRV, WARNING, "Open %s before opening this device.\n", main_netdev->name); return -EAGAIN; } netif_carrier_off(dev); vadapter->tx_ring->vmdq_netdev = dev; vadapter->rx_ring->vmdq_netdev = dev; if (is_valid_ether_addr(dev->dev_addr)) { igb_del_mac_filter(adapter, dev->dev_addr, hw_queue); igb_add_mac_filter(adapter, dev->dev_addr, hw_queue); } netif_carrier_on(dev); return 0; }
int bnxt_get_vf_config(struct net_device *dev, int vf_id, struct ifla_vf_info *ivi) { struct bnxt *bp = netdev_priv(dev); struct bnxt_vf_info *vf; int rc; rc = bnxt_vf_ndo_prep(bp, vf_id); if (rc) return rc; ivi->vf = vf_id; vf = &bp->pf.vf[vf_id]; if (is_valid_ether_addr(vf->mac_addr)) memcpy(&ivi->mac, vf->mac_addr, ETH_ALEN); else memcpy(&ivi->mac, vf->vf_mac_addr, ETH_ALEN); ivi->max_tx_rate = vf->max_tx_rate; ivi->min_tx_rate = vf->min_tx_rate; ivi->vlan = vf->vlan; if (vf->flags & BNXT_VF_QOS) ivi->qos = vf->vlan >> VLAN_PRIO_SHIFT; else
int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count) { int rc = 0, attempts = 0; struct vfpf_acquire_tlv *req = &bp->vf2pf_mbox->req.acquire; struct pfvf_acquire_resp_tlv *resp = &bp->vf2pf_mbox->resp.acquire_resp; u32 vf_id; bool resources_acquired = false; /* clear mailbox and prep first tlv */ bnx2x_vfpf_prep(bp, &req->first_tlv, CHANNEL_TLV_ACQUIRE, sizeof(*req)); if (bnx2x_get_vf_id(bp, &vf_id)) { rc = -EAGAIN; goto out; } req->vfdev_info.vf_id = vf_id; req->vfdev_info.vf_os = 0; req->resc_request.num_rxqs = rx_count; req->resc_request.num_txqs = tx_count; req->resc_request.num_sbs = bp->igu_sb_cnt; req->resc_request.num_mac_filters = VF_ACQUIRE_MAC_FILTERS; req->resc_request.num_mc_filters = VF_ACQUIRE_MC_FILTERS; /* pf 2 vf bulletin board address */ req->bulletin_addr = bp->pf2vf_bulletin_mapping; /* add list termination tlv */ bnx2x_add_tlv(bp, req, req->first_tlv.tl.length, CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv)); /* output tlvs list */ bnx2x_dp_tlv_list(bp, req); while (!resources_acquired) { DP(BNX2X_MSG_SP, "attempting to acquire resources\n"); /* send acquire request */ rc = bnx2x_send_msg2pf(bp, &resp->hdr.status, bp->vf2pf_mbox_mapping); /* PF timeout */ if (rc) goto out; /* copy acquire response from buffer to bp */ memcpy(&bp->acquire_resp, resp, sizeof(bp->acquire_resp)); attempts++; /* test whether the PF accepted our request. If not, humble the * the request and try again. */ if (bp->acquire_resp.hdr.status == PFVF_STATUS_SUCCESS) { DP(BNX2X_MSG_SP, "resources acquired\n"); resources_acquired = true; } else if (bp->acquire_resp.hdr.status == PFVF_STATUS_NO_RESOURCE && attempts < VF_ACQUIRE_THRESH) { DP(BNX2X_MSG_SP, "PF unwilling to fulfill resource request. Try PF recommended amount\n"); /* humble our request */ req->resc_request.num_txqs = bp->acquire_resp.resc.num_txqs; req->resc_request.num_rxqs = bp->acquire_resp.resc.num_rxqs; req->resc_request.num_sbs = bp->acquire_resp.resc.num_sbs; req->resc_request.num_mac_filters = bp->acquire_resp.resc.num_mac_filters; req->resc_request.num_vlan_filters = bp->acquire_resp.resc.num_vlan_filters; req->resc_request.num_mc_filters = bp->acquire_resp.resc.num_mc_filters; /* Clear response buffer */ memset(&bp->vf2pf_mbox->resp, 0, sizeof(union pfvf_tlvs)); } else { /* PF reports error */ BNX2X_ERR("Failed to get the requested amount of resources: %d. Breaking...\n", bp->acquire_resp.hdr.status); rc = -EAGAIN; goto out; } } /* get HW info */ bp->common.chip_id |= (bp->acquire_resp.pfdev_info.chip_num & 0xffff); bp->link_params.chip_id = bp->common.chip_id; bp->db_size = bp->acquire_resp.pfdev_info.db_size; bp->common.int_block = INT_BLOCK_IGU; bp->common.chip_port_mode = CHIP_2_PORT_MODE; bp->igu_dsb_id = -1; bp->mf_ov = 0; bp->mf_mode = 0; bp->common.flash_size = 0; bp->flags |= NO_WOL_FLAG | NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG | NO_FCOE_FLAG; bp->igu_sb_cnt = 1; bp->igu_base_sb = bp->acquire_resp.resc.hw_sbs[0].hw_sb_id; strlcpy(bp->fw_ver, bp->acquire_resp.pfdev_info.fw_ver, sizeof(bp->fw_ver)); if (is_valid_ether_addr(bp->acquire_resp.resc.current_mac_addr)) memcpy(bp->dev->dev_addr, bp->acquire_resp.resc.current_mac_addr, ETH_ALEN); out: bnx2x_vfpf_finalize(bp, &req->first_tlv); return rc; }
static void _rtl_init_mac80211(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtlpriv); struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); struct ieee80211_supported_band *sband; if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY && rtlhal->bandset == BAND_ON_BOTH) { /* 1: 2.4 G bands */ /* <1> use mac->bands as mem for hw->wiphy->bands */ sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]); /* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ] * to default value(1T1R) */ memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz, sizeof(struct ieee80211_supported_band)); /* <3> init ht cap base on ant_num */ _rtl_init_hw_ht_capab(hw, &sband->ht_cap); /* <4> set mac->sband to wiphy->sband */ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; /* 2: 5 G bands */ /* <1> use mac->bands as mem for hw->wiphy->bands */ sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]); /* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ] * to default value(1T1R) */ memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), &rtl_band_5ghz, sizeof(struct ieee80211_supported_band)); /* <3> init ht cap base on ant_num */ _rtl_init_hw_ht_capab(hw, &sband->ht_cap); /* <4> set mac->sband to wiphy->sband */ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; } else { if (rtlhal->current_bandtype == BAND_ON_2_4G) { /* <1> use mac->bands as mem for hw->wiphy->bands */ sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]); /* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ] * to default value(1T1R) */ memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz, sizeof(struct ieee80211_supported_band)); /* <3> init ht cap base on ant_num */ _rtl_init_hw_ht_capab(hw, &sband->ht_cap); /* <4> set mac->sband to wiphy->sband */ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; } else if (rtlhal->current_bandtype == BAND_ON_5G) { /* <1> use mac->bands as mem for hw->wiphy->bands */ sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]); /* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ] * to default value(1T1R) */ memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), &rtl_band_5ghz, sizeof(struct ieee80211_supported_band)); /* <3> init ht cap base on ant_num */ _rtl_init_hw_ht_capab(hw, &sband->ht_cap); /* <4> set mac->sband to wiphy->sband */ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; } else { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Err BAND %d\n", rtlhal->current_bandtype); } } /* <5> set hw caps */ hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_AMPDU_AGGREGATION | IEEE80211_HW_CONNECTION_MONITOR | /* IEEE80211_HW_SUPPORTS_CQM_RSSI | */ IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0; /* swlps or hwlps has been set in diff chip in init_sw_vars */ if (rtlpriv->psc.swctrl_lps) hw->flags |= IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | /* IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */ 0; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); hw->wiphy->rts_threshold = 2347; hw->queues = AC_MAX; hw->extra_tx_headroom = RTL_TX_HEADER_SIZE; /* TODO: Correct this value for our hw */ /* TODO: define these hard code value */ hw->channel_change_time = 100; hw->max_listen_interval = 10; hw->max_rate_tries = 4; /* hw->max_rates = 1; */ hw->sta_data_size = sizeof(struct rtl_sta_info); /* <6> mac address */ if (is_valid_ether_addr(rtlefuse->dev_addr)) { SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr); } else { u8 rtlmac1[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 }; get_random_bytes((rtlmac1 + (ETH_ALEN - 1)), 1); SET_IEEE80211_PERM_ADDR(hw, rtlmac1); } }
/* * Return NULL if skb is handled * note: already called with rcu_read_lock */ rx_handler_result_t br_handle_frame(struct sk_buff **pskb) { struct net_bridge_port *p; struct sk_buff *skb = *pskb; const unsigned char *dest = eth_hdr(skb)->h_dest; br_should_route_hook_t *rhook; if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) return RX_HANDLER_PASS; if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) goto drop; skb = skb_share_check(skb, GFP_ATOMIC); if (!skb) return RX_HANDLER_CONSUMED; p = br_port_get_rcu(skb->dev); if (unlikely(is_link_local_ether_addr(dest))) { /* * See IEEE 802.1D Table 7-10 Reserved addresses * * Assignment Value * Bridge Group Address 01-80-C2-00-00-00 * (MAC Control) 802.3 01-80-C2-00-00-01 * (Link Aggregation) 802.3 01-80-C2-00-00-02 * 802.1X PAE address 01-80-C2-00-00-03 * * 802.1AB LLDP 01-80-C2-00-00-0E * * Others reserved for future standardization */ switch (dest[5]) { case 0x00: /* Bridge Group Address */ /* If STP is turned off, then must forward to keep loop detection */ if (p->br->stp_enabled == BR_NO_STP) goto forward; break; case 0x01: /* IEEE MAC (Pause) */ goto drop; default: /* Allow selective forwarding for most other protocols */ if (p->br->group_fwd_mask & (1u << dest[5])) goto forward; } /* Deliver packet to local host only */ if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, NULL, br_handle_local_finish)) { return RX_HANDLER_CONSUMED; /* consumed by filter */ } else { *pskb = skb; return RX_HANDLER_PASS; /* continue processing */ } } forward: switch (p->state) { case BR_STATE_FORWARDING: rhook = rcu_dereference(br_should_route_hook); if (rhook) { if ((*rhook)(skb)) { *pskb = skb; return RX_HANDLER_PASS; } dest = eth_hdr(skb)->h_dest; } /* fall through */ case BR_STATE_LEARNING: if (ether_addr_equal(p->br->dev->dev_addr, dest)) skb->pkt_type = PACKET_HOST; NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, br_handle_frame_finish); break; default: drop: kfree_skb(skb); } return RX_HANDLER_CONSUMED; }
static int r92su_open(struct net_device *ndev) { struct r92su *r92su = ndev->ml_priv; int err = -EAGAIN; if (!is_valid_ether_addr(ndev->dev_addr)) return -EADDRNOTAVAIL; /* Since the firmware starts sending frames as soon as its initialized, * we have to have a valid current_channel set, otherwise the rx-path * would panic */ r92su->current_channel = &r92su->wdev.wiphy->bands[NL80211_BAND_2GHZ]->channels[0]; err = r92su_load_firmware(r92su); if (err) return err; mutex_lock(&r92su->lock); if (!r92su_is_stopped(r92su)) { err = -EAGAIN; goto out; } err = r92su_hw_early_mac_setup(r92su); if (err) goto out; err = r92su_upload_firmware(r92su); if (err) goto out; /* uploading the firmware resets the c2h and h2c command counters */ r92su_cmd_init(r92su); err = r92su_hw_late_mac_setup(r92su); if (err) goto out; err = r92su_init_mac(r92su); if (err) goto out; if (!r92su_is_stopped(r92su)) { err = -EAGAIN; goto out; } switch (r92su->wdev.iftype) { case NL80211_IFTYPE_MONITOR: r92su_set_state(r92su, R92SU_CONNECTED); break; default: r92su_set_state(r92su, R92SU_OPEN); break; } r92su_hw_queue_service_work(r92su); out: mutex_unlock(&r92su->lock); return err; }
static int bgmac_fixed_phy_register(struct bgmac *bgmac) { struct fixed_phy_status fphy_status = { .link = 1, .speed = SPEED_1000, .duplex = DUPLEX_FULL, }; struct phy_device *phy_dev; int err; phy_dev = fixed_phy_register(PHY_POLL, &fphy_status, -1, NULL); if (!phy_dev || IS_ERR(phy_dev)) { bgmac_err(bgmac, "Failed to register fixed PHY device\n"); return -ENODEV; } err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link, PHY_INTERFACE_MODE_MII); if (err) { bgmac_err(bgmac, "Connecting PHY failed\n"); return err; } bgmac->phy_dev = phy_dev; return err; } static int bgmac_mii_register(struct bgmac *bgmac) { struct mii_bus *mii_bus; struct phy_device *phy_dev; char bus_id[MII_BUS_ID_SIZE + 3]; int err = 0; if (bgmac_is_bcm4707_family(bgmac)) return bgmac_fixed_phy_register(bgmac); mii_bus = mdiobus_alloc(); if (!mii_bus) return -ENOMEM; mii_bus->name = "bgmac mii bus"; sprintf(mii_bus->id, "%s-%d-%d", "bgmac", bgmac->core->bus->num, bgmac->core->core_unit); mii_bus->priv = bgmac; mii_bus->read = bgmac_mii_read; mii_bus->write = bgmac_mii_write; mii_bus->parent = &bgmac->core->dev; mii_bus->phy_mask = ~(1 << bgmac->phyaddr); err = mdiobus_register(mii_bus); if (err) { bgmac_err(bgmac, "Registration of mii bus failed\n"); goto err_free_bus; } bgmac->mii_bus = mii_bus; /* Connect to the PHY */ snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, mii_bus->id, bgmac->phyaddr); phy_dev = phy_connect(bgmac->net_dev, bus_id, &bgmac_adjust_link, PHY_INTERFACE_MODE_MII); if (IS_ERR(phy_dev)) { bgmac_err(bgmac, "PHY connection failed\n"); err = PTR_ERR(phy_dev); goto err_unregister_bus; } bgmac->phy_dev = phy_dev; return err; err_unregister_bus: mdiobus_unregister(mii_bus); err_free_bus: mdiobus_free(mii_bus); return err; } static void bgmac_mii_unregister(struct bgmac *bgmac) { struct mii_bus *mii_bus = bgmac->mii_bus; mdiobus_unregister(mii_bus); mdiobus_free(mii_bus); } /************************************************** * BCMA bus ops **************************************************/ /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipattach */ static int bgmac_probe(struct bcma_device *core) { struct net_device *net_dev; struct bgmac *bgmac; struct ssb_sprom *sprom = &core->bus->sprom; u8 *mac; int err; switch (core->core_unit) { case 0: mac = sprom->et0mac; break; case 1: mac = sprom->et1mac; break; case 2: mac = sprom->et2mac; break; default: pr_err("Unsupported core_unit %d\n", core->core_unit); return -ENOTSUPP; } if (!is_valid_ether_addr(mac)) { dev_err(&core->dev, "Invalid MAC addr: %pM\n", mac); eth_random_addr(mac); dev_warn(&core->dev, "Using random MAC: %pM\n", mac); } /* This (reset &) enable is not preset in specs or reference driver but * Broadcom does it in arch PCI code when enabling fake PCI device. */ bcma_core_enable(core, 0); /* Allocation and references */ net_dev = alloc_etherdev(sizeof(*bgmac)); if (!net_dev) return -ENOMEM; net_dev->netdev_ops = &bgmac_netdev_ops; net_dev->irq = core->irq; net_dev->ethtool_ops = &bgmac_ethtool_ops; bgmac = netdev_priv(net_dev); bgmac->net_dev = net_dev; bgmac->core = core; bcma_set_drvdata(core, bgmac); /* Defaults */ memcpy(bgmac->net_dev->dev_addr, mac, ETH_ALEN); /* On BCM4706 we need common core to access PHY */ if (core->id.id == BCMA_CORE_4706_MAC_GBIT && !core->bus->drv_gmac_cmn.core) { bgmac_err(bgmac, "GMAC CMN core not found (required for BCM4706)\n"); err = -ENODEV; goto err_netdev_free; } bgmac->cmn = core->bus->drv_gmac_cmn.core; switch (core->core_unit) { case 0: bgmac->phyaddr = sprom->et0phyaddr; break; case 1: bgmac->phyaddr = sprom->et1phyaddr; break; case 2: bgmac->phyaddr = sprom->et2phyaddr; break; } bgmac->phyaddr &= BGMAC_PHY_MASK; if (bgmac->phyaddr == BGMAC_PHY_MASK) { bgmac_err(bgmac, "No PHY found\n"); err = -ENODEV; goto err_netdev_free; } bgmac_info(bgmac, "Found PHY addr: %d%s\n", bgmac->phyaddr, bgmac->phyaddr == BGMAC_PHY_NOREGS ? " (NOREGS)" : ""); if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) { bgmac_err(bgmac, "PCI setup not implemented\n"); err = -ENOTSUPP; goto err_netdev_free; } bgmac_chip_reset(bgmac); /* For Northstar, we have to take all GMAC core out of reset */ if (bgmac_is_bcm4707_family(bgmac)) { struct bcma_device *ns_core; int ns_gmac; /* Northstar has 4 GMAC cores */ for (ns_gmac = 0; ns_gmac < 4; ns_gmac++) { /* As Northstar requirement, we have to reset all GMACs * before accessing one. bgmac_chip_reset() call * bcma_core_enable() for this core. Then the other * three GMACs didn't reset. We do it here. */ ns_core = bcma_find_core_unit(core->bus, BCMA_CORE_MAC_GBIT, ns_gmac); if (ns_core && !bcma_core_is_enabled(ns_core)) bcma_core_enable(ns_core, 0); } } err = bgmac_dma_alloc(bgmac); if (err) { bgmac_err(bgmac, "Unable to alloc memory for DMA\n"); goto err_netdev_free; } bgmac->int_mask = BGMAC_IS_ERRMASK | BGMAC_IS_RX | BGMAC_IS_TX_MASK; if (bcm47xx_nvram_getenv("et0_no_txint", NULL, 0) == 0) bgmac->int_mask &= ~BGMAC_IS_TX_MASK; /* TODO: reset the external phy. Specs are needed */ bgmac_phy_reset(bgmac); bgmac->has_robosw = !!(core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETROBO); if (bgmac->has_robosw) bgmac_warn(bgmac, "Support for Roboswitch not implemented\n"); if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM) bgmac_warn(bgmac, "Support for ADMtek ethernet switch not implemented\n"); netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT); err = bgmac_mii_register(bgmac); if (err) { bgmac_err(bgmac, "Cannot register MDIO\n"); goto err_dma_free; } net_dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; net_dev->hw_features = net_dev->features; net_dev->vlan_features = net_dev->features; err = register_netdev(bgmac->net_dev); if (err) { bgmac_err(bgmac, "Cannot register net device\n"); goto err_mii_unregister; } netif_carrier_off(net_dev); return 0; err_mii_unregister: bgmac_mii_unregister(bgmac); err_dma_free: bgmac_dma_free(bgmac); err_netdev_free: bcma_set_drvdata(core, NULL); free_netdev(net_dev); return err; } static void bgmac_remove(struct bcma_device *core) { struct bgmac *bgmac = bcma_get_drvdata(core); unregister_netdev(bgmac->net_dev); bgmac_mii_unregister(bgmac); netif_napi_del(&bgmac->napi); bgmac_dma_free(bgmac); bcma_set_drvdata(core, NULL); free_netdev(bgmac->net_dev); } static struct bcma_driver bgmac_bcma_driver = { .name = KBUILD_MODNAME, .id_table = bgmac_bcma_tbl, .probe = bgmac_probe, .remove = bgmac_remove, }; static int __init bgmac_init(void) { int err; err = bcma_driver_register(&bgmac_bcma_driver); if (err) return err; pr_info("Broadcom 47xx GBit MAC driver loaded\n"); return 0; }
/****************************************************************************** * struct platform_driver functions *****************************************************************************/ static int ftmac100_probe(struct platform_device *pdev) { struct resource *res; int irq; struct net_device *netdev; struct ftmac100 *priv; int err; if (!pdev) return -ENODEV; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENXIO; irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; /* setup net_device */ netdev = alloc_etherdev(sizeof(*priv)); if (!netdev) { err = -ENOMEM; goto err_alloc_etherdev; } SET_NETDEV_DEV(netdev, &pdev->dev); netdev->ethtool_ops = &ftmac100_ethtool_ops; netdev->netdev_ops = &ftmac100_netdev_ops; platform_set_drvdata(pdev, netdev); /* setup private data */ priv = netdev_priv(netdev); priv->netdev = netdev; priv->dev = &pdev->dev; spin_lock_init(&priv->tx_lock); /* initialize NAPI */ netif_napi_add(netdev, &priv->napi, ftmac100_poll, 64); /* map io memory */ priv->res = request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev)); if (!priv->res) { dev_err(&pdev->dev, "Could not reserve memory region\n"); err = -ENOMEM; goto err_req_mem; } priv->base = ioremap(res->start, resource_size(res)); if (!priv->base) { dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n"); err = -EIO; goto err_ioremap; } priv->irq = irq; /* initialize struct mii_if_info */ priv->mii.phy_id = 0; priv->mii.phy_id_mask = 0x1f; priv->mii.reg_num_mask = 0x1f; priv->mii.dev = netdev; priv->mii.mdio_read = ftmac100_mdio_read; priv->mii.mdio_write = ftmac100_mdio_write; /* register network device */ err = register_netdev(netdev); if (err) { dev_err(&pdev->dev, "Failed to register netdev\n"); goto err_register_netdev; } netdev_info(netdev, "irq %d, mapped at %p\n", priv->irq, priv->base); if (!is_valid_ether_addr(netdev->dev_addr)) { eth_hw_addr_random(netdev); netdev_info(netdev, "generated random MAC address %pM\n", netdev->dev_addr); } return 0; err_register_netdev: iounmap(priv->base); err_ioremap: release_resource(priv->res); err_req_mem: netif_napi_del(&priv->napi); free_netdev(netdev); err_alloc_etherdev: return err; }
static int __devinit bfin_mac_probe(struct platform_device *pdev) { struct net_device *ndev; struct bfin_mac_local *lp; struct platform_device *pd; int rc; ndev = alloc_etherdev(sizeof(struct bfin_mac_local)); if (!ndev) { dev_err(&pdev->dev, "Cannot allocate net device!\n"); return -ENOMEM; } SET_NETDEV_DEV(ndev, &pdev->dev); platform_set_drvdata(pdev, ndev); lp = netdev_priv(ndev); /* Grab the MAC address in the MAC */ *(__le32 *) (&(ndev->dev_addr[0])) = cpu_to_le32(bfin_read_EMAC_ADDRLO()); *(__le16 *) (&(ndev->dev_addr[4])) = cpu_to_le16((u16) bfin_read_EMAC_ADDRHI()); /* probe mac */ /*todo: how to proble? which is revision_register */ bfin_write_EMAC_ADDRLO(0x12345678); if (bfin_read_EMAC_ADDRLO() != 0x12345678) { dev_err(&pdev->dev, "Cannot detect Blackfin on-chip ethernet MAC controller!\n"); rc = -ENODEV; goto out_err_probe_mac; } /* * Is it valid? (Did bootloader initialize it?) * Grab the MAC from the board somehow * this is done in the arch/blackfin/mach-bfxxx/boards/eth_mac.c */ if (!is_valid_ether_addr(ndev->dev_addr)) bfin_get_ether_addr(ndev->dev_addr); /* If still not valid, get a random one */ if (!is_valid_ether_addr(ndev->dev_addr)) random_ether_addr(ndev->dev_addr); setup_mac_addr(ndev->dev_addr); if (!pdev->dev.platform_data) { dev_err(&pdev->dev, "Cannot get platform device bfin_mii_bus!\n"); rc = -ENODEV; goto out_err_probe_mac; } pd = pdev->dev.platform_data; lp->mii_bus = platform_get_drvdata(pd); lp->mii_bus->priv = ndev; rc = mii_probe(ndev); if (rc) { dev_err(&pdev->dev, "MII Probe failed!\n"); goto out_err_mii_probe; } /* Fill in the fields of the device structure with ethernet values. */ ether_setup(ndev); ndev->netdev_ops = &bfin_mac_netdev_ops; ndev->ethtool_ops = &bfin_mac_ethtool_ops; spin_lock_init(&lp->lock); /* now, enable interrupts */ /* register irq handler */ rc = request_irq(IRQ_MAC_RX, bfin_mac_interrupt, IRQF_DISABLED, "EMAC_RX", ndev); if (rc) { dev_err(&pdev->dev, "Cannot request Blackfin MAC RX IRQ!\n"); rc = -EBUSY; goto out_err_request_irq; } rc = register_netdev(ndev); if (rc) { dev_err(&pdev->dev, "Cannot register net device!\n"); goto out_err_reg_ndev; } /* now, print out the card info, in a short format.. */ dev_info(&pdev->dev, "%s, Version %s\n", DRV_DESC, DRV_VERSION); return 0; out_err_reg_ndev: free_irq(IRQ_MAC_RX, ndev); out_err_request_irq: out_err_mii_probe: mdiobus_unregister(lp->mii_bus); mdiobus_free(lp->mii_bus); peripheral_free_list(pin_req); out_err_probe_mac: platform_set_drvdata(pdev, NULL); free_netdev(ndev); return rc; }
/** * attach to the WL device. * * Attach to the WL device identified by vendor and device parameters. * regs is a host accessible memory address pointing to WL device registers. * * is called in brcms_bcma_probe() context, therefore no locking required. */ static struct brcms_info *brcms_attach(struct bcma_device *pdev) { struct brcms_info *wl = NULL; int unit, err; struct ieee80211_hw *hw; u8 perm[ETH_ALEN]; unit = n_adapters_found; err = 0; if (unit < 0) return NULL; /* allocate private info */ hw = bcma_get_drvdata(pdev); if (hw != NULL) wl = hw->priv; if (WARN_ON(hw == NULL) || WARN_ON(wl == NULL)) return NULL; wl->wiphy = hw->wiphy; atomic_set(&wl->callbacks, 0); init_waitqueue_head(&wl->tx_flush_wq); /* setup the bottom half handler */ tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl); spin_lock_init(&wl->lock); spin_lock_init(&wl->isr_lock); /* common load-time initialization */ wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err); if (!wl->wlc) { wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n", KBUILD_MODNAME, err); goto fail; } wl->pub = brcms_c_pub(wl->wlc); wl->pub->ieee_hw = hw; /* register our interrupt handler */ if (request_irq(pdev->irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit); goto fail; } wl->irq = pdev->irq; /* register module */ brcms_c_module_register(wl->pub, "linux", wl, NULL); if (ieee_hw_init(hw)) { wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit, __func__); goto fail; } brcms_c_regd_init(wl->wlc); memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN); if (WARN_ON(!is_valid_ether_addr(perm))) goto fail; SET_IEEE80211_PERM_ADDR(hw, perm); err = ieee80211_register_hw(hw); if (err) wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status" "%d\n", __func__, err); if (wl->pub->srom_ccode[0] && regulatory_hint(wl->wiphy, wl->pub->srom_ccode)) wiphy_err(wl->wiphy, "%s: regulatory hint failed\n", __func__); brcms_debugfs_attach(wl->pub); brcms_debugfs_create_files(wl->pub); n_adapters_found++; return wl; fail: brcms_free(wl); return NULL; }
/** * et131x_set_mac_addr - handler to change the MAC address for the device * @netdev: device whose MAC is to be changed * @new_mac: the desired MAC address * * Returns 0 on success, errno on failure (as defined in errno.h) * * IMPLEMENTED BY : blux http://berndlux.de 22.01.2007 21:14 */ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac) { int result = 0; struct et131x_adapter *adapter = netdev_priv(netdev); struct sockaddr *address = new_mac; /* begin blux */ if (adapter == NULL) return -ENODEV; /* Make sure the requested MAC is valid */ if (!is_valid_ether_addr(address->sa_data)) return -EINVAL; /* Stop the netif queue */ netif_stop_queue(netdev); /* Stop the Tx and Rx DMA engines */ et131x_rx_dma_disable(adapter); et131x_tx_dma_disable(adapter); /* Disable device interrupts */ et131x_disable_interrupts(adapter); et131x_handle_send_interrupt(adapter); et131x_handle_recv_interrupt(adapter); /* Set the new MAC */ /* netdev->set_mac_address = &new_mac; */ /* netdev->mtu = new_mtu; */ memcpy(netdev->dev_addr, address->sa_data, netdev->addr_len); printk(KERN_INFO "%s: Setting MAC address to %pM\n", netdev->name, netdev->dev_addr); /* Free Rx DMA memory */ et131x_adapter_memory_free(adapter); /* Set the config parameter for Jumbo Packet support */ /* adapter->RegistryJumboPacket = new_mtu + 14; */ /* blux: not needet here, we'll change the MAC */ et131x_soft_reset(adapter); /* Alloc and init Rx DMA memory */ result = et131x_adapter_memory_alloc(adapter); if (result != 0) { dev_err(&adapter->pdev->dev, "Change MAC failed; couldn't re-alloc DMA memory\n"); return result; } et131x_init_send(adapter); et131x_hwaddr_init(adapter); /* Init the device with the new settings */ et131x_adapter_setup(adapter); /* Enable interrupts */ if (adapter->Flags & fMP_ADAPTER_INTERRUPT_IN_USE) et131x_enable_interrupts(adapter); /* Restart the Tx and Rx DMA engines */ et131x_rx_dma_enable(adapter); et131x_tx_dma_enable(adapter); /* Restart the netif queue */ netif_wake_queue(netdev); return result; }
int bgmac_phy_connect_direct(struct bgmac *bgmac) { struct fixed_phy_status fphy_status = { .link = 1, .speed = SPEED_1000, .duplex = DUPLEX_FULL, }; struct phy_device *phy_dev; int err; phy_dev = fixed_phy_register(PHY_POLL, &fphy_status, -1, NULL); if (!phy_dev || IS_ERR(phy_dev)) { dev_err(bgmac->dev, "Failed to register fixed PHY device\n"); return -ENODEV; } err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link, PHY_INTERFACE_MODE_MII); if (err) { dev_err(bgmac->dev, "Connecting PHY failed\n"); return err; } return err; } EXPORT_SYMBOL_GPL(bgmac_phy_connect_direct); struct bgmac *bgmac_alloc(struct device *dev) { struct net_device *net_dev; struct bgmac *bgmac; /* Allocation and references */ net_dev = devm_alloc_etherdev(dev, sizeof(*bgmac)); if (!net_dev) return NULL; net_dev->netdev_ops = &bgmac_netdev_ops; net_dev->ethtool_ops = &bgmac_ethtool_ops; bgmac = netdev_priv(net_dev); bgmac->dev = dev; bgmac->net_dev = net_dev; return bgmac; } EXPORT_SYMBOL_GPL(bgmac_alloc); int bgmac_enet_probe(struct bgmac *bgmac) { struct net_device *net_dev = bgmac->net_dev; int err; net_dev->irq = bgmac->irq; SET_NETDEV_DEV(net_dev, bgmac->dev); dev_set_drvdata(bgmac->dev, bgmac); if (!is_valid_ether_addr(net_dev->dev_addr)) { dev_err(bgmac->dev, "Invalid MAC addr: %pM\n", net_dev->dev_addr); eth_hw_addr_random(net_dev); dev_warn(bgmac->dev, "Using random MAC: %pM\n", net_dev->dev_addr); } /* This (reset &) enable is not preset in specs or reference driver but * Broadcom does it in arch PCI code when enabling fake PCI device. */ bgmac_clk_enable(bgmac, 0); /* This seems to be fixing IRQ by assigning OOB #6 to the core */ if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK)) { if (bgmac->feature_flags & BGMAC_FEAT_IRQ_ID_OOB_6) bgmac_idm_write(bgmac, BCMA_OOB_SEL_OUT_A30, 0x86); } bgmac_chip_reset(bgmac); err = bgmac_dma_alloc(bgmac); if (err) { dev_err(bgmac->dev, "Unable to alloc memory for DMA\n"); goto err_out; } bgmac->int_mask = BGMAC_IS_ERRMASK | BGMAC_IS_RX | BGMAC_IS_TX_MASK; if (bcm47xx_nvram_getenv("et0_no_txint", NULL, 0) == 0) bgmac->int_mask &= ~BGMAC_IS_TX_MASK; netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT); err = bgmac_phy_connect(bgmac); if (err) { dev_err(bgmac->dev, "Cannot connect to phy\n"); goto err_dma_free; } net_dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; net_dev->hw_features = net_dev->features; net_dev->vlan_features = net_dev->features; err = register_netdev(bgmac->net_dev); if (err) { dev_err(bgmac->dev, "Cannot register net device\n"); goto err_phy_disconnect; } netif_carrier_off(net_dev); return 0; err_phy_disconnect: phy_disconnect(net_dev->phydev); err_dma_free: bgmac_dma_free(bgmac); err_out: return err; } EXPORT_SYMBOL_GPL(bgmac_enet_probe); void bgmac_enet_remove(struct bgmac *bgmac) { unregister_netdev(bgmac->net_dev); phy_disconnect(bgmac->net_dev->phydev); netif_napi_del(&bgmac->napi); bgmac_dma_free(bgmac); free_netdev(bgmac->net_dev); }
static void tsi108_check_phy(net_device * dev) { tsi108_prv_data *data = netdev_priv(dev); u16 sumstat; u32 mac_cfg2_reg, portctrl_reg; u32 fdx_flag = 0, reg_update = 0; /* Do a dummy read, as for some reason the first read * after a link becomes up returns link down, even if * it's been a while since the link came up. */ spin_lock(&phy_lock); if (!data->phy_ok) goto out; tsi108_read_mii(data, PHY_STAT, NULL); if (!(tsi108_read_mii(data, PHY_STAT, NULL) & PHY_STAT_LINKUP)) { if (data->link_up == 1) { netif_stop_queue(dev); data->link_up = 0; printk(KERN_NOTICE "%s : link is down\n", dev->name); netif_carrier_off(dev); } goto out; } { mac_cfg2_reg = TSI108_ETH_READ_REG(TSI108_MAC_CFG2); portctrl_reg = TSI108_ETH_READ_REG(TSI108_EC_PORTCTRL); sumstat = tsi108_read_mii(data, PHY_SUM_STAT, NULL); switch (sumstat & PHY_SUM_STAT_SPEED_MASK) { case PHY_SUM_STAT_1000T_FD: fdx_flag++; case PHY_SUM_STAT_1000T_HD: if (data->speed != 1000) { mac_cfg2_reg &= ~TSI108_MAC_CFG2_IFACE_MASK; mac_cfg2_reg |= TSI108_MAC_CFG2_GIG; portctrl_reg &= ~TSI108_EC_PORTCTRL_NOGIG; data->speed = 1000; reg_update++; } break; case PHY_SUM_STAT_100TX_FD: fdx_flag++; case PHY_SUM_STAT_100TX_HD: if (data->speed != 100) { mac_cfg2_reg &= ~TSI108_MAC_CFG2_IFACE_MASK; mac_cfg2_reg |= TSI108_MAC_CFG2_NOGIG; portctrl_reg |= TSI108_EC_PORTCTRL_NOGIG; data->speed = 100; reg_update++; } break; case PHY_SUM_STAT_10T_FD: fdx_flag++; case PHY_SUM_STAT_10T_HD: if (data->speed != 10) { mac_cfg2_reg &= ~TSI108_MAC_CFG2_IFACE_MASK; mac_cfg2_reg |= TSI108_MAC_CFG2_NOGIG; portctrl_reg |= TSI108_EC_PORTCTRL_NOGIG; data->speed = 10; reg_update++; } break; default: if (net_ratelimit()) printk(KERN_ERR "PHY reported invalid speed," KERN_ERR " summary status %x\n", sumstat); goto out; } if (fdx_flag) { if (data->duplex != 2) { mac_cfg2_reg |= TSI108_MAC_CFG2_FULLDUPLEX; portctrl_reg &= ~TSI108_EC_PORTCTRL_HALFDUPLEX; data->duplex = 2; reg_update++; } } else { if (data->duplex != 1) { mac_cfg2_reg &= ~TSI108_MAC_CFG2_FULLDUPLEX; portctrl_reg |= TSI108_EC_PORTCTRL_HALFDUPLEX; data->duplex = 1; reg_update++; } } if (reg_update) { TSI108_ETH_WRITE_REG(TSI108_MAC_CFG2, mac_cfg2_reg); mb(); TSI108_ETH_WRITE_REG(TSI108_EC_PORTCTRL, portctrl_reg); mb(); } } if (data->link_up == 0) { /* The manual says it can take 3-4 usecs for the speed change * to take effect. */ udelay(5); spin_lock(&data->txlock); if (netif_queue_stopped(dev) && is_valid_ether_addr(dev->dev_addr) && data->txfree) netif_wake_queue(dev); data->link_up = 1; spin_unlock(&data->txlock); printk("%s : link is up: %dMb %s-duplex\n", dev->name, data->speed, (data->duplex == 2) ? "full" : "half"); netif_carrier_on(dev); } out: spin_unlock(&phy_lock); }
/** * stmmac_pltfr_probe * @pdev: platform device pointer * Description: platform_device probe function. It allocates * the necessary resources and invokes the main to init * the net device, register the mdio bus etc. */ static int stmmac_pltfr_probe(struct platform_device *pdev) { int ret = 0; struct resource *res; void __iomem *addr = NULL; struct stmmac_priv *priv = NULL; struct plat_stmmacenet_data *plat_dat = NULL; const char *mac = NULL; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; if (!request_mem_region(res->start, resource_size(res), pdev->name)) { pr_err("%s: ERROR: memory allocation failed" "cannot get the I/O addr 0x%x\n", __func__, (unsigned int)res->start); return -EBUSY; } addr = ioremap(res->start, resource_size(res)); if (!addr) { pr_err("%s: ERROR: memory mapping failed", __func__); ret = -ENOMEM; goto out_release_region; } plat_dat = dev_get_platdata(&pdev->dev); if (pdev->dev.of_node) { if (!plat_dat) plat_dat = devm_kzalloc(&pdev->dev, sizeof(struct plat_stmmacenet_data), GFP_KERNEL); if (!plat_dat) { pr_err("%s: ERROR: no memory", __func__); ret = -ENOMEM; goto out_unmap; } ret = stmmac_probe_config_dt(pdev, plat_dat, &mac); if (ret) { pr_err("%s: main dt probe failed", __func__); goto out_unmap; } } else if (is_valid_ether_addr(plat_dat->dev_addr)) { mac = plat_dat->dev_addr; } /* Custom initialisation (if needed)*/ #if 0 if (plat_dat->init) { ret = plat_dat->init(pdev); if (unlikely(ret)) goto out_unmap; } #endif priv = stmmac_dvr_probe(&(pdev->dev), plat_dat, addr); if (!priv) { pr_err("%s: main driver probe failed", __func__); goto out_unmap; } /* Get MAC address if available (DT) */ if (mac) memcpy(priv->dev->dev_addr, mac, ETH_ALEN); /* Get the MAC information */ priv->dev->irq = platform_get_irq_byname(pdev, "macirq"); if (priv->dev->irq == -ENXIO) { pr_err("%s: ERROR: MAC IRQ configuration " "information not found\n", __func__); ret = -ENXIO; goto out_unmap; } /* * On some platforms e.g. SPEAr the wake up irq differs from the mac irq * The external wake up irq can be passed through the platform code * named as "eth_wake_irq" * * In case the wake up interrupt is not passed from the platform * so the driver will continue to use the mac irq (ndev->irq) */ priv->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq"); if (priv->wol_irq == -ENXIO) priv->wol_irq = priv->dev->irq; priv->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi"); platform_set_drvdata(pdev, priv->dev); pr_debug("STMMAC platform driver registration completed"); return 0; out_unmap: iounmap(addr); platform_set_drvdata(pdev, NULL); out_release_region: release_mem_region(res->start, resource_size(res)); return ret; }
static int __devinit bfin_mac_probe(struct platform_device *pdev) { struct net_device *ndev; struct bfin_mac_local *lp; struct platform_device *pd; int rc; ndev = alloc_etherdev(sizeof(struct bfin_mac_local)); if (!ndev) { dev_err(&pdev->dev, "Cannot allocate net device!\n"); return -ENOMEM; } SET_NETDEV_DEV(ndev, &pdev->dev); platform_set_drvdata(pdev, ndev); lp = netdev_priv(ndev); *(__le32 *) (&(ndev->dev_addr[0])) = cpu_to_le32(bfin_read_EMAC_ADDRLO()); *(__le16 *) (&(ndev->dev_addr[4])) = cpu_to_le16((u16) bfin_read_EMAC_ADDRHI()); bfin_write_EMAC_ADDRLO(0x12345678); if (bfin_read_EMAC_ADDRLO() != 0x12345678) { dev_err(&pdev->dev, "Cannot detect Blackfin on-chip ethernet MAC controller!\n"); rc = -ENODEV; goto out_err_probe_mac; } if (!is_valid_ether_addr(ndev->dev_addr)) bfin_get_ether_addr(ndev->dev_addr); if (!is_valid_ether_addr(ndev->dev_addr)) random_ether_addr(ndev->dev_addr); setup_mac_addr(ndev->dev_addr); if (!pdev->dev.platform_data) { dev_err(&pdev->dev, "Cannot get platform device bfin_mii_bus!\n"); rc = -ENODEV; goto out_err_probe_mac; } pd = pdev->dev.platform_data; lp->mii_bus = platform_get_drvdata(pd); lp->mii_bus->priv = ndev; rc = mii_probe(ndev); if (rc) { dev_err(&pdev->dev, "MII Probe failed!\n"); goto out_err_mii_probe; } ether_setup(ndev); ndev->netdev_ops = &bfin_mac_netdev_ops; ndev->ethtool_ops = &bfin_mac_ethtool_ops; spin_lock_init(&lp->lock); rc = request_irq(IRQ_MAC_RX, bfin_mac_interrupt, IRQF_DISABLED, "EMAC_RX", ndev); if (rc) { dev_err(&pdev->dev, "Cannot request Blackfin MAC RX IRQ!\n"); rc = -EBUSY; goto out_err_request_irq; } rc = register_netdev(ndev); if (rc) { dev_err(&pdev->dev, "Cannot register net device!\n"); goto out_err_reg_ndev; } dev_info(&pdev->dev, "%s, Version %s\n", DRV_DESC, DRV_VERSION); return 0; out_err_reg_ndev: free_irq(IRQ_MAC_RX, ndev); out_err_request_irq: out_err_mii_probe: mdiobus_unregister(lp->mii_bus); mdiobus_free(lp->mii_bus); peripheral_free_list(pin_req); out_err_probe_mac: platform_set_drvdata(pdev, NULL); free_netdev(ndev); return rc; }
int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) { struct p54_common *priv = dev->priv; struct eeprom_pda_wrap *wrap; struct pda_entry *entry; unsigned int data_len, entry_len; void *tmp; int err; u8 *end = (u8 *)eeprom + len; u16 synth = 0; u16 crc16 = ~0; wrap = (struct eeprom_pda_wrap *) eeprom; entry = (void *)wrap->data + le16_to_cpu(wrap->len); /* verify that at least the entry length/code fits */ while ((u8 *)entry <= end - sizeof(*entry)) { entry_len = le16_to_cpu(entry->len); data_len = ((entry_len - 1) << 1); /* abort if entry exceeds whole structure */ if ((u8 *)entry + sizeof(*entry) + data_len > end) break; switch (le16_to_cpu(entry->code)) { case PDR_MAC_ADDRESS: if (data_len != ETH_ALEN) break; SET_IEEE80211_PERM_ADDR(dev, entry->data); break; case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS: if (priv->output_limit) break; err = p54_convert_output_limits(dev, entry->data, data_len); if (err) goto err; break; case PDR_PRISM_PA_CAL_CURVE_DATA: { struct pda_pa_curve_data *curve_data = (struct pda_pa_curve_data *)entry->data; if (data_len < sizeof(*curve_data)) { err = -EINVAL; goto err; } switch (curve_data->cal_method_rev) { case 0: err = p54_convert_rev0(dev, curve_data); break; case 1: err = p54_convert_rev1(dev, curve_data); break; default: wiphy_err(dev->wiphy, "unknown curve data revision %d\n", curve_data->cal_method_rev); err = -ENODEV; break; } if (err) goto err; } break; case PDR_PRISM_ZIF_TX_IQ_CALIBRATION: priv->iq_autocal = kmemdup(entry->data, data_len, GFP_KERNEL); if (!priv->iq_autocal) { err = -ENOMEM; goto err; } priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry); break; case PDR_DEFAULT_COUNTRY: p54_parse_default_country(dev, entry->data, data_len); break; case PDR_INTERFACE_LIST: tmp = entry->data; while ((u8 *)tmp < entry->data + data_len) { struct exp_if *exp_if = tmp; if (exp_if->if_id == cpu_to_le16(IF_ID_ISL39000)) synth = le16_to_cpu(exp_if->variant); tmp += sizeof(*exp_if); } break; case PDR_HARDWARE_PLATFORM_COMPONENT_ID: if (data_len < 2) break; priv->version = *(u8 *)(entry->data + 1); break; case PDR_RSSI_LINEAR_APPROXIMATION: case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND: case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED: err = p54_parse_rssical(dev, entry->data, data_len, le16_to_cpu(entry->code)); if (err) goto err; break; case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2: { struct pda_custom_wrapper *pda = (void *) entry->data; __le16 *src; u16 *dst; int i; if (priv->rssi_db || data_len < sizeof(*pda)) break; priv->rssi_db = p54_convert_db(pda, data_len); if (!priv->rssi_db) break; src = (void *) priv->rssi_db->data; dst = (void *) priv->rssi_db->data; for (i = 0; i < priv->rssi_db->entries; i++) *(dst++) = (s16) le16_to_cpu(*(src++)); } break; case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: { struct pda_custom_wrapper *pda = (void *) entry->data; if (priv->output_limit || data_len < sizeof(*pda)) break; priv->output_limit = p54_convert_db(pda, data_len); } break; case PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM: { struct pda_custom_wrapper *pda = (void *) entry->data; if (priv->curve_data || data_len < sizeof(*pda)) break; priv->curve_data = p54_convert_db(pda, data_len); } break; case PDR_END: crc16 = ~crc_ccitt(crc16, (u8 *) entry, sizeof(*entry)); if (crc16 != le16_to_cpup((__le16 *)entry->data)) { wiphy_err(dev->wiphy, "eeprom failed checksum " "test!\n"); err = -ENOMSG; goto err; } else { goto good_eeprom; } break; default: break; } crc16 = crc_ccitt(crc16, (u8 *)entry, (entry_len + 1) * 2); entry = (void *)entry + (entry_len + 1) * 2; } wiphy_err(dev->wiphy, "unexpected end of eeprom data.\n"); err = -ENODATA; goto err; good_eeprom: if (!synth || !priv->iq_autocal || !priv->output_limit || !priv->curve_data) { wiphy_err(dev->wiphy, "not all required entries found in eeprom!\n"); err = -EINVAL; goto err; } err = p54_generate_channel_lists(dev); if (err) goto err; priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK; if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW) p54_init_xbow_synth(priv); if (!(synth & PDR_SYNTH_24_GHZ_DISABLED)) dev->wiphy->bands[IEEE80211_BAND_2GHZ] = priv->band_table[IEEE80211_BAND_2GHZ]; if (!(synth & PDR_SYNTH_5_GHZ_DISABLED)) dev->wiphy->bands[IEEE80211_BAND_5GHZ] = priv->band_table[IEEE80211_BAND_5GHZ]; if ((synth & PDR_SYNTH_RX_DIV_MASK) == PDR_SYNTH_RX_DIV_SUPPORTED) priv->rx_diversity_mask = 3; if ((synth & PDR_SYNTH_TX_DIV_MASK) == PDR_SYNTH_TX_DIV_SUPPORTED) priv->tx_diversity_mask = 3; if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { u8 perm_addr[ETH_ALEN]; wiphy_warn(dev->wiphy, "Invalid hwaddr! Using randomly generated MAC addr\n"); random_ether_addr(perm_addr); SET_IEEE80211_PERM_ADDR(dev, perm_addr); } priv->cur_rssi = &p54_rssi_default; wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n", dev->wiphy->perm_addr, priv->version, p54_rf_chips[priv->rxhw]); return 0; err: kfree(priv->iq_autocal); kfree(priv->output_limit); kfree(priv->curve_data); kfree(priv->rssi_db); priv->iq_autocal = NULL; priv->output_limit = NULL; priv->curve_data = NULL; priv->rssi_db = NULL; wiphy_err(dev->wiphy, "eeprom parse failed!\n"); return err; }
static int fec_get_hwaddr(struct eth_device *dev, int dev_id, unsigned char *mac) { imx_get_mac_from_fuse(dev_id, mac); return !is_valid_ether_addr(mac); }
/* Search EMAC board, allocate space and register it */ static int emac_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct emac_board_info *db; struct net_device *ndev; int ret = 0; const char *mac_addr; ndev = alloc_etherdev(sizeof(struct emac_board_info)); if (!ndev) { dev_err(&pdev->dev, "could not allocate device.\n"); return -ENOMEM; } SET_NETDEV_DEV(ndev, &pdev->dev); db = netdev_priv(ndev); memset(db, 0, sizeof(*db)); db->dev = &pdev->dev; db->ndev = ndev; db->pdev = pdev; db->msg_enable = netif_msg_init(debug, EMAC_DEFAULT_MSG_ENABLE); spin_lock_init(&db->lock); db->membase = of_iomap(np, 0); if (!db->membase) { dev_err(&pdev->dev, "failed to remap registers\n"); ret = -ENOMEM; goto out; } /* fill in parameters for net-dev structure */ ndev->base_addr = (unsigned long)db->membase; ndev->irq = irq_of_parse_and_map(np, 0); if (ndev->irq == -ENXIO) { netdev_err(ndev, "No irq resource\n"); ret = ndev->irq; goto out_iounmap; } db->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(db->clk)) { ret = PTR_ERR(db->clk); goto out_iounmap; } ret = clk_prepare_enable(db->clk); if (ret) { dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n", ret); goto out_iounmap; } ret = sunxi_sram_claim(&pdev->dev); if (ret) { dev_err(&pdev->dev, "Error couldn't map SRAM to device\n"); goto out_clk_disable_unprepare; } db->phy_node = of_parse_phandle(np, "phy", 0); if (!db->phy_node) { dev_err(&pdev->dev, "no associated PHY\n"); ret = -ENODEV; goto out_release_sram; } /* Read MAC-address from DT */ mac_addr = of_get_mac_address(np); if (mac_addr) memcpy(ndev->dev_addr, mac_addr, ETH_ALEN); /* Check if the MAC address is valid, if not get a random one */ if (!is_valid_ether_addr(ndev->dev_addr)) { eth_hw_addr_random(ndev); dev_warn(&pdev->dev, "using random MAC address %pM\n", ndev->dev_addr); } db->emacrx_completed_flag = 1; emac_powerup(ndev); emac_reset(db); ndev->netdev_ops = &emac_netdev_ops; ndev->watchdog_timeo = msecs_to_jiffies(watchdog); ndev->ethtool_ops = &emac_ethtool_ops; platform_set_drvdata(pdev, ndev); /* Carrier starts down, phylib will bring it up */ netif_carrier_off(ndev); ret = register_netdev(ndev); if (ret) { dev_err(&pdev->dev, "Registering netdev failed!\n"); ret = -ENODEV; goto out_release_sram; } dev_info(&pdev->dev, "%s: at %p, IRQ %d MAC: %pM\n", ndev->name, db->membase, ndev->irq, ndev->dev_addr); return 0; out_release_sram: sunxi_sram_release(&pdev->dev); out_clk_disable_unprepare: clk_disable_unprepare(db->clk); out_iounmap: iounmap(db->membase); out: dev_err(db->dev, "not found (%d).\n", ret); free_netdev(ndev); return ret; }
static int xgbe_probe(struct platform_device *pdev) { struct xgbe_prv_data *pdata; struct xgbe_hw_if *hw_if; struct xgbe_desc_if *desc_if; struct net_device *netdev; struct device *dev = &pdev->dev; struct resource *res; const char *phy_mode; unsigned int i; int ret; DBGPR("--> xgbe_probe\n"); netdev = alloc_etherdev_mq(sizeof(struct xgbe_prv_data), XGBE_MAX_DMA_CHANNELS); if (!netdev) { dev_err(dev, "alloc_etherdev failed\n"); ret = -ENOMEM; goto err_alloc; } SET_NETDEV_DEV(netdev, dev); pdata = netdev_priv(netdev); pdata->netdev = netdev; pdata->pdev = pdev; pdata->adev = ACPI_COMPANION(dev); pdata->dev = dev; platform_set_drvdata(pdev, netdev); spin_lock_init(&pdata->lock); mutex_init(&pdata->xpcs_mutex); mutex_init(&pdata->rss_mutex); spin_lock_init(&pdata->tstamp_lock); /* Check if we should use ACPI or DT */ pdata->use_acpi = (!pdata->adev || acpi_disabled) ? 0 : 1; /* Set and validate the number of descriptors for a ring */ BUILD_BUG_ON_NOT_POWER_OF_2(XGBE_TX_DESC_CNT); pdata->tx_desc_count = XGBE_TX_DESC_CNT; if (pdata->tx_desc_count & (pdata->tx_desc_count - 1)) { dev_err(dev, "tx descriptor count (%d) is not valid\n", pdata->tx_desc_count); ret = -EINVAL; goto err_io; } BUILD_BUG_ON_NOT_POWER_OF_2(XGBE_RX_DESC_CNT); pdata->rx_desc_count = XGBE_RX_DESC_CNT; if (pdata->rx_desc_count & (pdata->rx_desc_count - 1)) { dev_err(dev, "rx descriptor count (%d) is not valid\n", pdata->rx_desc_count); ret = -EINVAL; goto err_io; } /* Obtain the mmio areas for the device */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); pdata->xgmac_regs = devm_ioremap_resource(dev, res); if (IS_ERR(pdata->xgmac_regs)) { dev_err(dev, "xgmac ioremap failed\n"); ret = PTR_ERR(pdata->xgmac_regs); goto err_io; } DBGPR(" xgmac_regs = %p\n", pdata->xgmac_regs); res = platform_get_resource(pdev, IORESOURCE_MEM, 1); pdata->xpcs_regs = devm_ioremap_resource(dev, res); if (IS_ERR(pdata->xpcs_regs)) { dev_err(dev, "xpcs ioremap failed\n"); ret = PTR_ERR(pdata->xpcs_regs); goto err_io; } DBGPR(" xpcs_regs = %p\n", pdata->xpcs_regs); /* Retrieve the MAC address */ ret = device_property_read_u8_array(dev, XGBE_MAC_ADDR_PROPERTY, pdata->mac_addr, sizeof(pdata->mac_addr)); if (ret || !is_valid_ether_addr(pdata->mac_addr)) { dev_err(dev, "invalid %s property\n", XGBE_MAC_ADDR_PROPERTY); if (!ret) ret = -EINVAL; goto err_io; } /* Retrieve the PHY mode - it must be "xgmii" */ ret = device_property_read_string(dev, XGBE_PHY_MODE_PROPERTY, &phy_mode); if (ret || strcmp(phy_mode, phy_modes(PHY_INTERFACE_MODE_XGMII))) { dev_err(dev, "invalid %s property\n", XGBE_PHY_MODE_PROPERTY); if (!ret) ret = -EINVAL; goto err_io; } pdata->phy_mode = PHY_INTERFACE_MODE_XGMII; /* Check for per channel interrupt support */ if (device_property_present(dev, XGBE_DMA_IRQS_PROPERTY)) pdata->per_channel_irq = 1; /* Obtain device settings unique to ACPI/OF */ if (pdata->use_acpi) ret = xgbe_acpi_support(pdata); else ret = xgbe_of_support(pdata); if (ret) goto err_io; /* Set the DMA coherency values */ if (pdata->coherent) { pdata->axdomain = XGBE_DMA_OS_AXDOMAIN; pdata->arcache = XGBE_DMA_OS_ARCACHE; pdata->awcache = XGBE_DMA_OS_AWCACHE; } else { pdata->axdomain = XGBE_DMA_SYS_AXDOMAIN; pdata->arcache = XGBE_DMA_SYS_ARCACHE; pdata->awcache = XGBE_DMA_SYS_AWCACHE; } /* Get the device interrupt */ ret = platform_get_irq(pdev, 0); if (ret < 0) { dev_err(dev, "platform_get_irq 0 failed\n"); goto err_io; } pdata->dev_irq = ret; netdev->irq = pdata->dev_irq; netdev->base_addr = (unsigned long)pdata->xgmac_regs; memcpy(netdev->dev_addr, pdata->mac_addr, netdev->addr_len); /* Set all the function pointers */ hw_if = pdata->hw_if = &default_xgbe_hw_if; desc_if = pdata->desc_if = &default_xgbe_desc_if; /* Issue software reset to device */ hw_if->exit(pdata); /* Populate the hardware features */ xgbe_get_all_hw_features(pdata); /* Set default configuration data */ xgbe_default_config(pdata); /* Set the DMA mask */ if (!dev->dma_mask) dev->dma_mask = &dev->coherent_dma_mask; ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(pdata->hw_feat.dma_width)); if (ret) { dev_err(dev, "dma_set_mask_and_coherent failed\n"); goto err_io; } /* Calculate the number of Tx and Rx rings to be created * -Tx (DMA) Channels map 1-to-1 to Tx Queues so set * the number of Tx queues to the number of Tx channels * enabled * -Rx (DMA) Channels do not map 1-to-1 so use the actual * number of Rx queues */ pdata->tx_ring_count = min_t(unsigned int, num_online_cpus(), pdata->hw_feat.tx_ch_cnt); pdata->tx_q_count = pdata->tx_ring_count; ret = netif_set_real_num_tx_queues(netdev, pdata->tx_ring_count); if (ret) { dev_err(dev, "error setting real tx queue count\n"); goto err_io; } pdata->rx_ring_count = min_t(unsigned int, netif_get_num_default_rss_queues(), pdata->hw_feat.rx_ch_cnt); pdata->rx_q_count = pdata->hw_feat.rx_q_cnt; ret = netif_set_real_num_rx_queues(netdev, pdata->rx_ring_count); if (ret) { dev_err(dev, "error setting real rx queue count\n"); goto err_io; } /* Initialize RSS hash key and lookup table */ netdev_rss_key_fill(pdata->rss_key, sizeof(pdata->rss_key)); for (i = 0; i < XGBE_RSS_MAX_TABLE_SIZE; i++) XGMAC_SET_BITS(pdata->rss_table[i], MAC_RSSDR, DMCH, i % pdata->rx_ring_count); XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, IP2TE, 1); XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, TCP4TE, 1); XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1); /* Prepare to regsiter with MDIO */ pdata->mii_bus_id = kasprintf(GFP_KERNEL, "%s", pdev->name); if (!pdata->mii_bus_id) { dev_err(dev, "failed to allocate mii bus id\n"); ret = -ENOMEM; goto err_io; } ret = xgbe_mdio_register(pdata); if (ret) goto err_bus_id; /* Set device operations */ netdev->netdev_ops = xgbe_get_netdev_ops(); netdev->ethtool_ops = xgbe_get_ethtool_ops(); #ifdef CONFIG_AMD_XGBE_DCB netdev->dcbnl_ops = xgbe_get_dcbnl_ops(); #endif /* Set device features */ netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_FILTER; if (pdata->hw_feat.rss) netdev->hw_features |= NETIF_F_RXHASH; netdev->vlan_features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6; netdev->features |= netdev->hw_features; pdata->netdev_features = netdev->features; netdev->priv_flags |= IFF_UNICAST_FLT; /* Use default watchdog timeout */ netdev->watchdog_timeo = 0; xgbe_init_rx_coalesce(pdata); xgbe_init_tx_coalesce(pdata); netif_carrier_off(netdev); ret = register_netdev(netdev); if (ret) { dev_err(dev, "net device registration failed\n"); goto err_reg_netdev; } xgbe_ptp_register(pdata); xgbe_debugfs_init(pdata); netdev_notice(netdev, "net device enabled\n"); DBGPR("<-- xgbe_probe\n"); return 0; err_reg_netdev: xgbe_mdio_unregister(pdata); err_bus_id: kfree(pdata->mii_bus_id); err_io: free_netdev(netdev); err_alloc: dev_notice(dev, "net device not enabled\n"); return ret; }
void fm10k_restore_rx_state(struct fm10k_intfc *interface) { struct net_device *netdev = interface->netdev; struct fm10k_hw *hw = &interface->hw; int xcast_mode; u16 vid, glort; /* restore our address if perm_addr is set */ if (hw->mac.type == fm10k_mac_vf) { if (is_valid_ether_addr(hw->mac.perm_addr)) { ether_addr_copy(hw->mac.addr, hw->mac.perm_addr); ether_addr_copy(netdev->perm_addr, hw->mac.perm_addr); ether_addr_copy(netdev->dev_addr, hw->mac.perm_addr); netdev->addr_assign_type &= ~NET_ADDR_RANDOM; } if (hw->mac.vlan_override) netdev->features &= ~NETIF_F_HW_VLAN_CTAG_RX; else netdev->features |= NETIF_F_HW_VLAN_CTAG_RX; } /* record glort for this interface */ glort = interface->glort; /* convert interface flags to xcast mode */ if (netdev->flags & IFF_PROMISC) xcast_mode = FM10K_XCAST_MODE_PROMISC; else if (netdev->flags & IFF_ALLMULTI) xcast_mode = FM10K_XCAST_MODE_ALLMULTI; else if (netdev->flags & (IFF_BROADCAST | IFF_MULTICAST)) xcast_mode = FM10K_XCAST_MODE_MULTI; else xcast_mode = FM10K_XCAST_MODE_NONE; fm10k_mbx_lock(interface); /* Enable logical port */ hw->mac.ops.update_lport_state(hw, glort, interface->glort_count, true); /* update VLAN table */ hw->mac.ops.update_vlan(hw, FM10K_VLAN_ALL, 0, xcast_mode == FM10K_XCAST_MODE_PROMISC); /* Add filter for VLAN 0 */ hw->mac.ops.update_vlan(hw, 0, 0, true); /* update table with current entries */ for (vid = hw->mac.default_vid ? fm10k_find_next_vlan(interface, 0) : 0; vid < VLAN_N_VID; vid = fm10k_find_next_vlan(interface, vid)) { hw->mac.ops.update_vlan(hw, vid, 0, true); hw->mac.ops.update_uc_addr(hw, glort, hw->mac.addr, vid, true, 0); } /* syncronize all of the addresses */ if (xcast_mode != FM10K_XCAST_MODE_PROMISC) { __dev_uc_sync(netdev, fm10k_uc_sync, fm10k_uc_unsync); if (xcast_mode != FM10K_XCAST_MODE_ALLMULTI) __dev_mc_sync(netdev, fm10k_mc_sync, fm10k_mc_unsync); } /* update xcast mode */ hw->mac.ops.update_xcast_mode(hw, glort, xcast_mode); fm10k_mbx_unlock(interface); /* record updated xcast mode state */ interface->xcast_mode = xcast_mode; /* Restore tunnel configuration */ fm10k_restore_vxlan_port(interface); }
static int __devinit p54u_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct ieee80211_hw *dev; struct p54u_priv *priv; int err; unsigned int i, recognized_pipes; DECLARE_MAC_BUF(mac); dev = p54_init_common(sizeof(*priv)); if (!dev) { printk(KERN_ERR "prism54usb: ieee80211 alloc failed\n"); return -ENOMEM; } priv = dev->priv; SET_IEEE80211_DEV(dev, &intf->dev); usb_set_intfdata(intf, dev); priv->udev = udev; usb_get_dev(udev); /* really lazy and simple way of figuring out if we're a 3887 */ /* TODO: should just stick the identification in the device table */ i = intf->altsetting->desc.bNumEndpoints; recognized_pipes = 0; while (i--) { switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) { case P54U_PIPE_DATA: case P54U_PIPE_MGMT: case P54U_PIPE_BRG: case P54U_PIPE_DEV: case P54U_PIPE_DATA | USB_DIR_IN: case P54U_PIPE_MGMT | USB_DIR_IN: case P54U_PIPE_BRG | USB_DIR_IN: case P54U_PIPE_DEV | USB_DIR_IN: case P54U_PIPE_INT | USB_DIR_IN: recognized_pipes++; } } priv->common.open = p54u_open; if (recognized_pipes < P54U_PIPE_NUMBER) { priv->hw_type = P54U_3887; priv->common.tx = p54u_tx_3887; } else { dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr); priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr); priv->common.tx = p54u_tx_net2280; } priv->common.stop = p54u_stop; if (priv->hw_type) err = p54u_upload_firmware_3887(dev); else err = p54u_upload_firmware_net2280(dev); if (err) goto err_free_dev; err = p54u_read_eeprom(dev); if (err) goto err_free_dev; if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { u8 perm_addr[ETH_ALEN]; printk(KERN_WARNING "prism54usb: Invalid hwaddr! Using randomly generated MAC addr\n"); random_ether_addr(perm_addr); SET_IEEE80211_PERM_ADDR(dev, perm_addr); } skb_queue_head_init(&priv->rx_queue); err = ieee80211_register_hw(dev); if (err) { printk(KERN_ERR "prism54usb: Cannot register netdevice\n"); goto err_free_dev; } printk(KERN_INFO "%s: hwaddr %s, isl38%02x\n", wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr), priv->common.version); return 0; err_free_dev: ieee80211_free_hw(dev); usb_set_intfdata(intf, NULL); usb_put_dev(udev); return err; }