Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
0002 /* Copyright 2017-2019 NXP */
0003 
0004 #include <linux/module.h>
0005 #include "enetc.h"
0006 
0007 #define ENETC_DRV_NAME_STR "ENETC VF driver"
0008 
0009 /* Messaging */
0010 static void enetc_msg_vsi_write_msg(struct enetc_hw *hw,
0011                     struct enetc_msg_swbd *msg)
0012 {
0013     u32 val;
0014 
0015     val = enetc_vsi_set_msize(msg->size) | lower_32_bits(msg->dma);
0016     enetc_wr(hw, ENETC_VSIMSGSNDAR1, upper_32_bits(msg->dma));
0017     enetc_wr(hw, ENETC_VSIMSGSNDAR0, val);
0018 }
0019 
0020 static int enetc_msg_vsi_send(struct enetc_si *si, struct enetc_msg_swbd *msg)
0021 {
0022     int timeout = 100;
0023     u32 vsimsgsr;
0024 
0025     enetc_msg_vsi_write_msg(&si->hw, msg);
0026 
0027     do {
0028         vsimsgsr = enetc_rd(&si->hw, ENETC_VSIMSGSR);
0029         if (!(vsimsgsr & ENETC_VSIMSGSR_MB))
0030             break;
0031 
0032         usleep_range(1000, 2000);
0033     } while (--timeout);
0034 
0035     if (!timeout)
0036         return -ETIMEDOUT;
0037 
0038     /* check for message delivery error */
0039     if (vsimsgsr & ENETC_VSIMSGSR_MS) {
0040         dev_err(&si->pdev->dev, "VSI command execute error: %d\n",
0041             ENETC_SIMSGSR_GET_MC(vsimsgsr));
0042         return -EIO;
0043     }
0044 
0045     return 0;
0046 }
0047 
0048 static int enetc_msg_vsi_set_primary_mac_addr(struct enetc_ndev_priv *priv,
0049                           struct sockaddr *saddr)
0050 {
0051     struct enetc_msg_cmd_set_primary_mac *cmd;
0052     struct enetc_msg_swbd msg;
0053     int err;
0054 
0055     msg.size = ALIGN(sizeof(struct enetc_msg_cmd_set_primary_mac), 64);
0056     msg.vaddr = dma_alloc_coherent(priv->dev, msg.size, &msg.dma,
0057                        GFP_KERNEL);
0058     if (!msg.vaddr) {
0059         dev_err(priv->dev, "Failed to alloc Tx msg (size: %d)\n",
0060             msg.size);
0061         return -ENOMEM;
0062     }
0063 
0064     cmd = (struct enetc_msg_cmd_set_primary_mac *)msg.vaddr;
0065     cmd->header.type = ENETC_MSG_CMD_MNG_MAC;
0066     cmd->header.id = ENETC_MSG_CMD_MNG_ADD;
0067     memcpy(&cmd->mac, saddr, sizeof(struct sockaddr));
0068 
0069     /* send the command and wait */
0070     err = enetc_msg_vsi_send(priv->si, &msg);
0071 
0072     dma_free_coherent(priv->dev, msg.size, msg.vaddr, msg.dma);
0073 
0074     return err;
0075 }
0076 
0077 static int enetc_vf_set_mac_addr(struct net_device *ndev, void *addr)
0078 {
0079     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0080     struct sockaddr *saddr = addr;
0081 
0082     if (!is_valid_ether_addr(saddr->sa_data))
0083         return -EADDRNOTAVAIL;
0084 
0085     return enetc_msg_vsi_set_primary_mac_addr(priv, saddr);
0086 }
0087 
0088 static int enetc_vf_set_features(struct net_device *ndev,
0089                  netdev_features_t features)
0090 {
0091     enetc_set_features(ndev, features);
0092 
0093     return 0;
0094 }
0095 
0096 static int enetc_vf_setup_tc(struct net_device *ndev, enum tc_setup_type type,
0097                  void *type_data)
0098 {
0099     switch (type) {
0100     case TC_SETUP_QDISC_MQPRIO:
0101         return enetc_setup_tc_mqprio(ndev, type_data);
0102     default:
0103         return -EOPNOTSUPP;
0104     }
0105 }
0106 
0107 /* Probing/ Init */
0108 static const struct net_device_ops enetc_ndev_ops = {
0109     .ndo_open       = enetc_open,
0110     .ndo_stop       = enetc_close,
0111     .ndo_start_xmit     = enetc_xmit,
0112     .ndo_get_stats      = enetc_get_stats,
0113     .ndo_set_mac_address    = enetc_vf_set_mac_addr,
0114     .ndo_set_features   = enetc_vf_set_features,
0115     .ndo_eth_ioctl      = enetc_ioctl,
0116     .ndo_setup_tc       = enetc_vf_setup_tc,
0117 };
0118 
0119 static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
0120                   const struct net_device_ops *ndev_ops)
0121 {
0122     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0123 
0124     SET_NETDEV_DEV(ndev, &si->pdev->dev);
0125     priv->ndev = ndev;
0126     priv->si = si;
0127     priv->dev = &si->pdev->dev;
0128     si->ndev = ndev;
0129 
0130     priv->msg_enable = (NETIF_MSG_IFUP << 1) - 1;
0131     ndev->netdev_ops = ndev_ops;
0132     enetc_set_ethtool_ops(ndev);
0133     ndev->watchdog_timeo = 5 * HZ;
0134     ndev->max_mtu = ENETC_MAX_MTU;
0135 
0136     ndev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM |
0137                 NETIF_F_HW_VLAN_CTAG_TX |
0138                 NETIF_F_HW_VLAN_CTAG_RX |
0139                 NETIF_F_HW_CSUM | NETIF_F_TSO | NETIF_F_TSO6;
0140     ndev->features = NETIF_F_HIGHDMA | NETIF_F_SG | NETIF_F_RXCSUM |
0141              NETIF_F_HW_VLAN_CTAG_TX |
0142              NETIF_F_HW_VLAN_CTAG_RX |
0143              NETIF_F_HW_CSUM | NETIF_F_TSO | NETIF_F_TSO6;
0144     ndev->vlan_features = NETIF_F_SG | NETIF_F_HW_CSUM |
0145                   NETIF_F_TSO | NETIF_F_TSO6;
0146 
0147     if (si->num_rss)
0148         ndev->hw_features |= NETIF_F_RXHASH;
0149 
0150     /* pick up primary MAC address from SI */
0151     enetc_load_primary_mac_addr(&si->hw, ndev);
0152 }
0153 
0154 static int enetc_vf_probe(struct pci_dev *pdev,
0155               const struct pci_device_id *ent)
0156 {
0157     struct enetc_ndev_priv *priv;
0158     struct net_device *ndev;
0159     struct enetc_si *si;
0160     int err;
0161 
0162     err = enetc_pci_probe(pdev, KBUILD_MODNAME, 0);
0163     if (err)
0164         return dev_err_probe(&pdev->dev, err, "PCI probing failed\n");
0165 
0166     si = pci_get_drvdata(pdev);
0167 
0168     enetc_get_si_caps(si);
0169 
0170     ndev = alloc_etherdev_mq(sizeof(*priv), ENETC_MAX_NUM_TXQS);
0171     if (!ndev) {
0172         err = -ENOMEM;
0173         dev_err(&pdev->dev, "netdev creation failed\n");
0174         goto err_alloc_netdev;
0175     }
0176 
0177     enetc_vf_netdev_setup(si, ndev, &enetc_ndev_ops);
0178 
0179     priv = netdev_priv(ndev);
0180 
0181     enetc_init_si_rings_params(priv);
0182 
0183     err = enetc_setup_cbdr(priv->dev, &si->hw, ENETC_CBDR_DEFAULT_SIZE,
0184                    &si->cbd_ring);
0185     if (err)
0186         goto err_setup_cbdr;
0187 
0188     err = enetc_alloc_si_resources(priv);
0189     if (err) {
0190         dev_err(&pdev->dev, "SI resource alloc failed\n");
0191         goto err_alloc_si_res;
0192     }
0193 
0194     err = enetc_configure_si(priv);
0195     if (err) {
0196         dev_err(&pdev->dev, "Failed to configure SI\n");
0197         goto err_config_si;
0198     }
0199 
0200     err = enetc_alloc_msix(priv);
0201     if (err) {
0202         dev_err(&pdev->dev, "MSIX alloc failed\n");
0203         goto err_alloc_msix;
0204     }
0205 
0206     err = register_netdev(ndev);
0207     if (err)
0208         goto err_reg_netdev;
0209 
0210     netif_carrier_off(ndev);
0211 
0212     return 0;
0213 
0214 err_reg_netdev:
0215     enetc_free_msix(priv);
0216 err_config_si:
0217 err_alloc_msix:
0218     enetc_free_si_resources(priv);
0219 err_alloc_si_res:
0220     enetc_teardown_cbdr(&si->cbd_ring);
0221 err_setup_cbdr:
0222     si->ndev = NULL;
0223     free_netdev(ndev);
0224 err_alloc_netdev:
0225     enetc_pci_remove(pdev);
0226 
0227     return err;
0228 }
0229 
0230 static void enetc_vf_remove(struct pci_dev *pdev)
0231 {
0232     struct enetc_si *si = pci_get_drvdata(pdev);
0233     struct enetc_ndev_priv *priv;
0234 
0235     priv = netdev_priv(si->ndev);
0236     unregister_netdev(si->ndev);
0237 
0238     enetc_free_msix(priv);
0239 
0240     enetc_free_si_resources(priv);
0241     enetc_teardown_cbdr(&si->cbd_ring);
0242 
0243     free_netdev(si->ndev);
0244 
0245     enetc_pci_remove(pdev);
0246 }
0247 
0248 static const struct pci_device_id enetc_vf_id_table[] = {
0249     { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_VF) },
0250     { 0, } /* End of table. */
0251 };
0252 MODULE_DEVICE_TABLE(pci, enetc_vf_id_table);
0253 
0254 static struct pci_driver enetc_vf_driver = {
0255     .name = KBUILD_MODNAME,
0256     .id_table = enetc_vf_id_table,
0257     .probe = enetc_vf_probe,
0258     .remove = enetc_vf_remove,
0259 };
0260 module_pci_driver(enetc_vf_driver);
0261 
0262 MODULE_DESCRIPTION(ENETC_DRV_NAME_STR);
0263 MODULE_LICENSE("Dual BSD/GPL");