root/drivers/net/ethernet/freescale/enetc/enetc_vf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. enetc_msg_vsi_write_msg
  2. enetc_msg_vsi_send
  3. enetc_msg_vsi_set_primary_mac_addr
  4. enetc_vf_set_mac_addr
  5. enetc_vf_set_features
  6. enetc_vf_netdev_setup
  7. enetc_vf_probe
  8. enetc_vf_remove

   1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
   2 /* Copyright 2017-2019 NXP */
   3 
   4 #include <linux/module.h>
   5 #include "enetc.h"
   6 
   7 #define ENETC_DRV_VER_MAJ 1
   8 #define ENETC_DRV_VER_MIN 0
   9 
  10 #define ENETC_DRV_VER_STR __stringify(ENETC_DRV_VER_MAJ) "." \
  11                           __stringify(ENETC_DRV_VER_MIN)
  12 static const char enetc_drv_ver[] = ENETC_DRV_VER_STR;
  13 #define ENETC_DRV_NAME_STR "ENETC VF driver"
  14 static const char enetc_drv_name[] = ENETC_DRV_NAME_STR;
  15 
  16 /* Messaging */
  17 static void enetc_msg_vsi_write_msg(struct enetc_hw *hw,
  18                                     struct enetc_msg_swbd *msg)
  19 {
  20         u32 val;
  21 
  22         val = enetc_vsi_set_msize(msg->size) | lower_32_bits(msg->dma);
  23         enetc_wr(hw, ENETC_VSIMSGSNDAR1, upper_32_bits(msg->dma));
  24         enetc_wr(hw, ENETC_VSIMSGSNDAR0, val);
  25 }
  26 
  27 static int enetc_msg_vsi_send(struct enetc_si *si, struct enetc_msg_swbd *msg)
  28 {
  29         int timeout = 100;
  30         u32 vsimsgsr;
  31 
  32         enetc_msg_vsi_write_msg(&si->hw, msg);
  33 
  34         do {
  35                 vsimsgsr = enetc_rd(&si->hw, ENETC_VSIMSGSR);
  36                 if (!(vsimsgsr & ENETC_VSIMSGSR_MB))
  37                         break;
  38 
  39                 usleep_range(1000, 2000);
  40         } while (--timeout);
  41 
  42         if (!timeout)
  43                 return -ETIMEDOUT;
  44 
  45         /* check for message delivery error */
  46         if (vsimsgsr & ENETC_VSIMSGSR_MS) {
  47                 dev_err(&si->pdev->dev, "VSI command execute error: %d\n",
  48                         ENETC_SIMSGSR_GET_MC(vsimsgsr));
  49                 return -EIO;
  50         }
  51 
  52         return 0;
  53 }
  54 
  55 static int enetc_msg_vsi_set_primary_mac_addr(struct enetc_ndev_priv *priv,
  56                                               struct sockaddr *saddr)
  57 {
  58         struct enetc_msg_cmd_set_primary_mac *cmd;
  59         struct enetc_msg_swbd msg;
  60         int err;
  61 
  62         msg.size = ALIGN(sizeof(struct enetc_msg_cmd_set_primary_mac), 64);
  63         msg.vaddr = dma_alloc_coherent(priv->dev, msg.size, &msg.dma,
  64                                        GFP_KERNEL);
  65         if (!msg.vaddr) {
  66                 dev_err(priv->dev, "Failed to alloc Tx msg (size: %d)\n",
  67                         msg.size);
  68                 return -ENOMEM;
  69         }
  70 
  71         cmd = (struct enetc_msg_cmd_set_primary_mac *)msg.vaddr;
  72         cmd->header.type = ENETC_MSG_CMD_MNG_MAC;
  73         cmd->header.id = ENETC_MSG_CMD_MNG_ADD;
  74         memcpy(&cmd->mac, saddr, sizeof(struct sockaddr));
  75 
  76         /* send the command and wait */
  77         err = enetc_msg_vsi_send(priv->si, &msg);
  78 
  79         dma_free_coherent(priv->dev, msg.size, msg.vaddr, msg.dma);
  80 
  81         return err;
  82 }
  83 
  84 static int enetc_vf_set_mac_addr(struct net_device *ndev, void *addr)
  85 {
  86         struct enetc_ndev_priv *priv = netdev_priv(ndev);
  87         struct sockaddr *saddr = addr;
  88         int err;
  89 
  90         if (!is_valid_ether_addr(saddr->sa_data))
  91                 return -EADDRNOTAVAIL;
  92 
  93         err = enetc_msg_vsi_set_primary_mac_addr(priv, saddr);
  94         if (err)
  95                 return err;
  96 
  97         return 0;
  98 }
  99 
 100 static int enetc_vf_set_features(struct net_device *ndev,
 101                                  netdev_features_t features)
 102 {
 103         return enetc_set_features(ndev, features);
 104 }
 105 
 106 /* Probing/ Init */
 107 static const struct net_device_ops enetc_ndev_ops = {
 108         .ndo_open               = enetc_open,
 109         .ndo_stop               = enetc_close,
 110         .ndo_start_xmit         = enetc_xmit,
 111         .ndo_get_stats          = enetc_get_stats,
 112         .ndo_set_mac_address    = enetc_vf_set_mac_addr,
 113         .ndo_set_features       = enetc_vf_set_features,
 114         .ndo_do_ioctl           = enetc_ioctl,
 115         .ndo_setup_tc           = enetc_setup_tc,
 116 };
 117 
 118 static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
 119                                   const struct net_device_ops *ndev_ops)
 120 {
 121         struct enetc_ndev_priv *priv = netdev_priv(ndev);
 122 
 123         SET_NETDEV_DEV(ndev, &si->pdev->dev);
 124         priv->ndev = ndev;
 125         priv->si = si;
 126         priv->dev = &si->pdev->dev;
 127         si->ndev = ndev;
 128 
 129         priv->msg_enable = (NETIF_MSG_IFUP << 1) - 1;
 130         ndev->netdev_ops = ndev_ops;
 131         enetc_set_ethtool_ops(ndev);
 132         ndev->watchdog_timeo = 5 * HZ;
 133         ndev->max_mtu = ENETC_MAX_MTU;
 134 
 135         ndev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | NETIF_F_HW_CSUM |
 136                             NETIF_F_HW_VLAN_CTAG_TX |
 137                             NETIF_F_HW_VLAN_CTAG_RX;
 138         ndev->features = NETIF_F_HIGHDMA | NETIF_F_SG |
 139                          NETIF_F_RXCSUM | NETIF_F_HW_CSUM |
 140                          NETIF_F_HW_VLAN_CTAG_TX |
 141                          NETIF_F_HW_VLAN_CTAG_RX;
 142 
 143         if (si->num_rss)
 144                 ndev->hw_features |= NETIF_F_RXHASH;
 145 
 146         if (si->errata & ENETC_ERR_TXCSUM) {
 147                 ndev->hw_features &= ~NETIF_F_HW_CSUM;
 148                 ndev->features &= ~NETIF_F_HW_CSUM;
 149         }
 150 
 151         /* pick up primary MAC address from SI */
 152         enetc_get_primary_mac_addr(&si->hw, ndev->dev_addr);
 153 }
 154 
 155 static int enetc_vf_probe(struct pci_dev *pdev,
 156                           const struct pci_device_id *ent)
 157 {
 158         struct enetc_ndev_priv *priv;
 159         struct net_device *ndev;
 160         struct enetc_si *si;
 161         int err;
 162 
 163         err = enetc_pci_probe(pdev, KBUILD_MODNAME, 0);
 164         if (err) {
 165                 dev_err(&pdev->dev, "PCI probing failed\n");
 166                 return err;
 167         }
 168 
 169         si = pci_get_drvdata(pdev);
 170 
 171         enetc_get_si_caps(si);
 172 
 173         ndev = alloc_etherdev_mq(sizeof(*priv), ENETC_MAX_NUM_TXQS);
 174         if (!ndev) {
 175                 err = -ENOMEM;
 176                 dev_err(&pdev->dev, "netdev creation failed\n");
 177                 goto err_alloc_netdev;
 178         }
 179 
 180         enetc_vf_netdev_setup(si, ndev, &enetc_ndev_ops);
 181 
 182         priv = netdev_priv(ndev);
 183 
 184         enetc_init_si_rings_params(priv);
 185 
 186         err = enetc_alloc_si_resources(priv);
 187         if (err) {
 188                 dev_err(&pdev->dev, "SI resource alloc failed\n");
 189                 goto err_alloc_si_res;
 190         }
 191 
 192         err = enetc_alloc_msix(priv);
 193         if (err) {
 194                 dev_err(&pdev->dev, "MSIX alloc failed\n");
 195                 goto err_alloc_msix;
 196         }
 197 
 198         err = register_netdev(ndev);
 199         if (err)
 200                 goto err_reg_netdev;
 201 
 202         netif_carrier_off(ndev);
 203 
 204         netif_info(priv, probe, ndev, "%s v%s\n",
 205                    enetc_drv_name, enetc_drv_ver);
 206 
 207         return 0;
 208 
 209 err_reg_netdev:
 210         enetc_free_msix(priv);
 211 err_alloc_msix:
 212         enetc_free_si_resources(priv);
 213 err_alloc_si_res:
 214         si->ndev = NULL;
 215         free_netdev(ndev);
 216 err_alloc_netdev:
 217         enetc_pci_remove(pdev);
 218 
 219         return err;
 220 }
 221 
 222 static void enetc_vf_remove(struct pci_dev *pdev)
 223 {
 224         struct enetc_si *si = pci_get_drvdata(pdev);
 225         struct enetc_ndev_priv *priv;
 226 
 227         priv = netdev_priv(si->ndev);
 228         netif_info(priv, drv, si->ndev, "%s v%s remove\n",
 229                    enetc_drv_name, enetc_drv_ver);
 230         unregister_netdev(si->ndev);
 231 
 232         enetc_free_msix(priv);
 233 
 234         enetc_free_si_resources(priv);
 235 
 236         free_netdev(si->ndev);
 237 
 238         enetc_pci_remove(pdev);
 239 }
 240 
 241 static const struct pci_device_id enetc_vf_id_table[] = {
 242         { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_VF) },
 243         { 0, } /* End of table. */
 244 };
 245 MODULE_DEVICE_TABLE(pci, enetc_vf_id_table);
 246 
 247 static struct pci_driver enetc_vf_driver = {
 248         .name = KBUILD_MODNAME,
 249         .id_table = enetc_vf_id_table,
 250         .probe = enetc_vf_probe,
 251         .remove = enetc_vf_remove,
 252 };
 253 module_pci_driver(enetc_vf_driver);
 254 
 255 MODULE_DESCRIPTION(ENETC_DRV_NAME_STR);
 256 MODULE_LICENSE("Dual BSD/GPL");
 257 MODULE_VERSION(ENETC_DRV_VER_STR);

/* [<][>][^][v][top][bottom][index][help] */