struct net_device *hfi1_vnic_alloc_rn(struct ib_device *device, u8 port_num, enum rdma_netdev_t type, const char *name, unsigned char name_assign_type, void (*setup)(struct net_device *)) { struct hfi1_devdata *dd = dd_from_ibdev(device); struct hfi1_vnic_vport_info *vinfo; struct net_device *netdev; struct rdma_netdev *rn; int i, size, rc; if (!port_num || (port_num > dd->num_pports)) return ERR_PTR(-EINVAL); if (type != RDMA_NETDEV_OPA_VNIC) return ERR_PTR(-EOPNOTSUPP); size = sizeof(struct opa_vnic_rdma_netdev) + sizeof(*vinfo); netdev = alloc_netdev_mqs(size, name, name_assign_type, setup, dd->chip_sdma_engines, HFI1_NUM_VNIC_CTXT); if (!netdev) return ERR_PTR(-ENOMEM); rn = netdev_priv(netdev); vinfo = opa_vnic_dev_priv(netdev); vinfo->dd = dd; vinfo->num_tx_q = dd->chip_sdma_engines; vinfo->num_rx_q = HFI1_NUM_VNIC_CTXT; vinfo->netdev = netdev; rn->set_id = hfi1_vnic_set_vesw_id; netdev->features = NETIF_F_HIGHDMA | NETIF_F_SG; netdev->hw_features = netdev->features; netdev->vlan_features = netdev->features; netdev->watchdog_timeo = msecs_to_jiffies(HFI_TX_TIMEOUT_MS); netdev->netdev_ops = &hfi1_netdev_ops; mutex_init(&vinfo->lock); for (i = 0; i < vinfo->num_rx_q; i++) { struct hfi1_vnic_rx_queue *rxq = &vinfo->rxq[i]; rxq->idx = i; rxq->vinfo = vinfo; rxq->netdev = netdev; netif_napi_add(netdev, &rxq->napi, hfi1_vnic_napi, 64); } rc = hfi1_vnic_init(vinfo); if (rc) goto init_fail; return netdev; init_fail: mutex_destroy(&vinfo->lock); free_netdev(netdev); return ERR_PTR(rc); }
static int r92su_alloc_netdev(struct r92su *r92su) { struct net_device *ndev; /* The firmware/hardware does not support multiple interfaces. * So, we are fine with just a single netdevice. */ ndev = alloc_netdev_mqs(0, "wlan%d", NET_NAME_UNKNOWN, r92su_if_setup, NUM_ACS, 1); if (!ndev) return -ENOMEM; ndev->ml_priv = r92su; r92su->wdev.netdev = ndev; ndev->ieee80211_ptr = &r92su->wdev; SET_NETDEV_DEV(ndev, wiphy_dev(r92su->wdev.wiphy)); return 0; }
int qtnf_core_net_attach(struct qtnf_wmac *mac, struct qtnf_vif *vif, const char *name, unsigned char name_assign_type, enum nl80211_iftype iftype) { struct wiphy *wiphy = priv_to_wiphy(mac); struct net_device *dev; void *qdev_vif; int ret; dev = alloc_netdev_mqs(sizeof(struct qtnf_vif *), name, name_assign_type, ether_setup, 1, 1); if (!dev) { memset(&vif->wdev, 0, sizeof(vif->wdev)); vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED; return -ENOMEM; } vif->netdev = dev; dev->netdev_ops = &qtnf_netdev_ops; dev->needs_free_netdev = true; dev_net_set(dev, wiphy_net(wiphy)); dev->ieee80211_ptr = &vif->wdev; dev->ieee80211_ptr->iftype = iftype; ether_addr_copy(dev->dev_addr, vif->mac_addr); SET_NETDEV_DEV(dev, wiphy_dev(wiphy)); dev->flags |= IFF_BROADCAST | IFF_MULTICAST; dev->watchdog_timeo = QTNF_DEF_WDOG_TIMEOUT; dev->tx_queue_len = 100; qdev_vif = netdev_priv(dev); *((void **)qdev_vif) = vif; SET_NETDEV_DEV(dev, mac->bus->dev); ret = register_netdevice(dev); if (ret) { free_netdev(dev); vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED; } return ret; }
struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs, unsigned int rxqs) { return alloc_netdev_mqs(sizeof_priv, "eth%d", ether_setup, txqs, rxqs); }
struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev, struct ib_device *ibdev, const char *name, void (*setup)(struct net_device *)) { const struct mlx5e_profile *profile; struct net_device *netdev; struct mlx5i_priv *ipriv; struct mlx5e_priv *epriv; struct rdma_netdev *rn; bool sub_interface; int nch; int err; if (mlx5i_check_required_hca_cap(mdev)) { mlx5_core_warn(mdev, "Accelerated mode is not supported\n"); return ERR_PTR(-EOPNOTSUPP); } /* TODO: Need to find a better way to check if child device*/ sub_interface = (mdev->mlx5e_res.pdn != 0); if (sub_interface) profile = mlx5i_pkey_get_profile(); else profile = &mlx5i_nic_profile; nch = profile->max_nch(mdev); netdev = alloc_netdev_mqs(sizeof(struct mlx5i_priv) + sizeof(struct mlx5e_priv), name, NET_NAME_UNKNOWN, setup, nch * MLX5E_MAX_NUM_TC, nch); if (!netdev) { mlx5_core_warn(mdev, "alloc_netdev_mqs failed\n"); return NULL; } ipriv = netdev_priv(netdev); epriv = mlx5i_epriv(netdev); epriv->wq = create_singlethread_workqueue("mlx5i"); if (!epriv->wq) goto err_free_netdev; ipriv->sub_interface = sub_interface; if (!ipriv->sub_interface) { err = mlx5i_pkey_qpn_ht_init(netdev); if (err) { mlx5_core_warn(mdev, "allocate qpn_to_netdev ht failed\n"); goto destroy_wq; } /* This should only be called once per mdev */ err = mlx5e_create_mdev_resources(mdev); if (err) goto destroy_ht; } profile->init(mdev, netdev, profile, ipriv); mlx5e_attach_netdev(epriv); netif_carrier_off(netdev); /* set rdma_netdev func pointers */ rn = &ipriv->rn; rn->hca = ibdev; rn->send = mlx5i_xmit; rn->attach_mcast = mlx5i_attach_mcast; rn->detach_mcast = mlx5i_detach_mcast; rn->set_id = mlx5i_set_pkey_index; return netdev; destroy_ht: mlx5i_pkey_qpn_ht_cleanup(netdev); destroy_wq: destroy_workqueue(epriv->wq); err_free_netdev: free_netdev(netdev); return NULL; }