123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700 |
- /**********************************************************************
- * Author: Cavium, Inc.
- *
- * Contact: support@cavium.com
- * Please include "LiquidIO" in the subject.
- *
- * Copyright (c) 2003-2017 Cavium, Inc.
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, Version 2, as
- * published by the Free Software Foundation.
- *
- * This file is distributed in the hope that it will be useful, but
- * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
- * NONINFRINGEMENT. See the GNU General Public License for more details.
- ***********************************************************************/
- #include <linux/pci.h>
- #include <linux/if_vlan.h>
- #include "liquidio_common.h"
- #include "octeon_droq.h"
- #include "octeon_iq.h"
- #include "response_manager.h"
- #include "octeon_device.h"
- #include "octeon_nic.h"
- #include "octeon_main.h"
- #include "octeon_network.h"
- #include <net/switchdev.h>
- #include "lio_vf_rep.h"
- #include "octeon_network.h"
- static int lio_vf_rep_open(struct net_device *ndev);
- static int lio_vf_rep_stop(struct net_device *ndev);
- static netdev_tx_t lio_vf_rep_pkt_xmit(struct sk_buff *skb,
- struct net_device *ndev);
- static void lio_vf_rep_tx_timeout(struct net_device *netdev);
- static int lio_vf_rep_phys_port_name(struct net_device *dev,
- char *buf, size_t len);
- static void lio_vf_rep_get_stats64(struct net_device *dev,
- struct rtnl_link_stats64 *stats64);
- static int lio_vf_rep_change_mtu(struct net_device *ndev, int new_mtu);
- static const struct net_device_ops lio_vf_rep_ndev_ops = {
- .ndo_open = lio_vf_rep_open,
- .ndo_stop = lio_vf_rep_stop,
- .ndo_start_xmit = lio_vf_rep_pkt_xmit,
- .ndo_tx_timeout = lio_vf_rep_tx_timeout,
- .ndo_get_phys_port_name = lio_vf_rep_phys_port_name,
- .ndo_get_stats64 = lio_vf_rep_get_stats64,
- .ndo_change_mtu = lio_vf_rep_change_mtu,
- };
- static void
- lio_vf_rep_send_sc_complete(struct octeon_device *oct,
- u32 status, void *ptr)
- {
- struct octeon_soft_command *sc = (struct octeon_soft_command *)ptr;
- struct lio_vf_rep_sc_ctx *ctx =
- (struct lio_vf_rep_sc_ctx *)sc->ctxptr;
- struct lio_vf_rep_resp *resp =
- (struct lio_vf_rep_resp *)sc->virtrptr;
- if (status != OCTEON_REQUEST_TIMEOUT && READ_ONCE(resp->status))
- WRITE_ONCE(resp->status, 0);
- complete(&ctx->complete);
- }
- static int
- lio_vf_rep_send_soft_command(struct octeon_device *oct,
- void *req, int req_size,
- void *resp, int resp_size)
- {
- int tot_resp_size = sizeof(struct lio_vf_rep_resp) + resp_size;
- int ctx_size = sizeof(struct lio_vf_rep_sc_ctx);
- struct octeon_soft_command *sc = NULL;
- struct lio_vf_rep_resp *rep_resp;
- struct lio_vf_rep_sc_ctx *ctx;
- void *sc_req;
- int err;
- sc = (struct octeon_soft_command *)
- octeon_alloc_soft_command(oct, req_size,
- tot_resp_size, ctx_size);
- if (!sc)
- return -ENOMEM;
- ctx = (struct lio_vf_rep_sc_ctx *)sc->ctxptr;
- memset(ctx, 0, ctx_size);
- init_completion(&ctx->complete);
- sc_req = (struct lio_vf_rep_req *)sc->virtdptr;
- memcpy(sc_req, req, req_size);
- rep_resp = (struct lio_vf_rep_resp *)sc->virtrptr;
- memset(rep_resp, 0, tot_resp_size);
- WRITE_ONCE(rep_resp->status, 1);
- sc->iq_no = 0;
- octeon_prepare_soft_command(oct, sc, OPCODE_NIC,
- OPCODE_NIC_VF_REP_CMD, 0, 0, 0);
- sc->callback = lio_vf_rep_send_sc_complete;
- sc->callback_arg = sc;
- sc->wait_time = LIO_VF_REP_REQ_TMO_MS;
- err = octeon_send_soft_command(oct, sc);
- if (err == IQ_SEND_FAILED)
- goto free_buff;
- wait_for_completion_timeout(&ctx->complete,
- msecs_to_jiffies
- (2 * LIO_VF_REP_REQ_TMO_MS));
- err = READ_ONCE(rep_resp->status) ? -EBUSY : 0;
- if (err)
- dev_err(&oct->pci_dev->dev, "VF rep send config failed\n");
- if (resp)
- memcpy(resp, (rep_resp + 1), resp_size);
- free_buff:
- octeon_free_soft_command(oct, sc);
- return err;
- }
- static int
- lio_vf_rep_open(struct net_device *ndev)
- {
- struct lio_vf_rep_desc *vf_rep = netdev_priv(ndev);
- struct lio_vf_rep_req rep_cfg;
- struct octeon_device *oct;
- int ret;
- oct = vf_rep->oct;
- memset(&rep_cfg, 0, sizeof(rep_cfg));
- rep_cfg.req_type = LIO_VF_REP_REQ_STATE;
- rep_cfg.ifidx = vf_rep->ifidx;
- rep_cfg.rep_state.state = LIO_VF_REP_STATE_UP;
- ret = lio_vf_rep_send_soft_command(oct, &rep_cfg,
- sizeof(rep_cfg), NULL, 0);
- if (ret) {
- dev_err(&oct->pci_dev->dev,
- "VF_REP open failed with err %d\n", ret);
- return -EIO;
- }
- atomic_set(&vf_rep->ifstate, (atomic_read(&vf_rep->ifstate) |
- LIO_IFSTATE_RUNNING));
- netif_carrier_on(ndev);
- netif_start_queue(ndev);
- return 0;
- }
- static int
- lio_vf_rep_stop(struct net_device *ndev)
- {
- struct lio_vf_rep_desc *vf_rep = netdev_priv(ndev);
- struct lio_vf_rep_req rep_cfg;
- struct octeon_device *oct;
- int ret;
- oct = vf_rep->oct;
- memset(&rep_cfg, 0, sizeof(rep_cfg));
- rep_cfg.req_type = LIO_VF_REP_REQ_STATE;
- rep_cfg.ifidx = vf_rep->ifidx;
- rep_cfg.rep_state.state = LIO_VF_REP_STATE_DOWN;
- ret = lio_vf_rep_send_soft_command(oct, &rep_cfg,
- sizeof(rep_cfg), NULL, 0);
- if (ret) {
- dev_err(&oct->pci_dev->dev,
- "VF_REP dev stop failed with err %d\n", ret);
- return -EIO;
- }
- atomic_set(&vf_rep->ifstate, (atomic_read(&vf_rep->ifstate) &
- ~LIO_IFSTATE_RUNNING));
- netif_tx_disable(ndev);
- netif_carrier_off(ndev);
- return 0;
- }
- static void
- lio_vf_rep_tx_timeout(struct net_device *ndev)
- {
- netif_trans_update(ndev);
- netif_wake_queue(ndev);
- }
- static void
- lio_vf_rep_get_stats64(struct net_device *dev,
- struct rtnl_link_stats64 *stats64)
- {
- struct lio_vf_rep_desc *vf_rep = netdev_priv(dev);
- /* Swap tx and rx stats as VF rep is a switch port */
- stats64->tx_packets = vf_rep->stats.rx_packets;
- stats64->tx_bytes = vf_rep->stats.rx_bytes;
- stats64->tx_dropped = vf_rep->stats.rx_dropped;
- stats64->rx_packets = vf_rep->stats.tx_packets;
- stats64->rx_bytes = vf_rep->stats.tx_bytes;
- stats64->rx_dropped = vf_rep->stats.tx_dropped;
- }
- static int
- lio_vf_rep_change_mtu(struct net_device *ndev, int new_mtu)
- {
- struct lio_vf_rep_desc *vf_rep = netdev_priv(ndev);
- struct lio_vf_rep_req rep_cfg;
- struct octeon_device *oct;
- int ret;
- oct = vf_rep->oct;
- memset(&rep_cfg, 0, sizeof(rep_cfg));
- rep_cfg.req_type = LIO_VF_REP_REQ_MTU;
- rep_cfg.ifidx = vf_rep->ifidx;
- rep_cfg.rep_mtu.mtu = cpu_to_be32(new_mtu);
- ret = lio_vf_rep_send_soft_command(oct, &rep_cfg,
- sizeof(rep_cfg), NULL, 0);
- if (ret) {
- dev_err(&oct->pci_dev->dev,
- "Change MTU failed with err %d\n", ret);
- return -EIO;
- }
- ndev->mtu = new_mtu;
- return 0;
- }
- static int
- lio_vf_rep_phys_port_name(struct net_device *dev,
- char *buf, size_t len)
- {
- struct lio_vf_rep_desc *vf_rep = netdev_priv(dev);
- struct octeon_device *oct = vf_rep->oct;
- int ret;
- ret = snprintf(buf, len, "pf%dvf%d", oct->pf_num,
- vf_rep->ifidx - oct->pf_num * 64 - 1);
- if (ret >= len)
- return -EOPNOTSUPP;
- return 0;
- }
- static struct net_device *
- lio_vf_rep_get_ndev(struct octeon_device *oct, int ifidx)
- {
- int vf_id, max_vfs = CN23XX_MAX_VFS_PER_PF + 1;
- int vfid_mask = max_vfs - 1;
- if (ifidx <= oct->pf_num * max_vfs ||
- ifidx >= oct->pf_num * max_vfs + max_vfs)
- return NULL;
- /* ifidx 1-63 for PF0 VFs
- * ifidx 65-127 for PF1 VFs
- */
- vf_id = (ifidx & vfid_mask) - 1;
- return oct->vf_rep_list.ndev[vf_id];
- }
- static void
- lio_vf_rep_copy_packet(struct octeon_device *oct,
- struct sk_buff *skb,
- int len)
- {
- if (likely(len > MIN_SKB_SIZE)) {
- struct octeon_skb_page_info *pg_info;
- unsigned char *va;
- pg_info = ((struct octeon_skb_page_info *)(skb->cb));
- if (pg_info->page) {
- va = page_address(pg_info->page) +
- pg_info->page_offset;
- memcpy(skb->data, va, MIN_SKB_SIZE);
- skb_put(skb, MIN_SKB_SIZE);
- }
- skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
- pg_info->page,
- pg_info->page_offset + MIN_SKB_SIZE,
- len - MIN_SKB_SIZE,
- LIO_RXBUFFER_SZ);
- } else {
- struct octeon_skb_page_info *pg_info =
- ((struct octeon_skb_page_info *)(skb->cb));
- skb_copy_to_linear_data(skb, page_address(pg_info->page) +
- pg_info->page_offset, len);
- skb_put(skb, len);
- put_page(pg_info->page);
- }
- }
- static int
- lio_vf_rep_pkt_recv(struct octeon_recv_info *recv_info, void *buf)
- {
- struct octeon_recv_pkt *recv_pkt = recv_info->recv_pkt;
- struct lio_vf_rep_desc *vf_rep;
- struct net_device *vf_ndev;
- struct octeon_device *oct;
- union octeon_rh *rh;
- struct sk_buff *skb;
- int i, ifidx;
- oct = lio_get_device(recv_pkt->octeon_id);
- if (!oct)
- goto free_buffers;
- skb = recv_pkt->buffer_ptr[0];
- rh = &recv_pkt->rh;
- ifidx = rh->r.ossp;
- vf_ndev = lio_vf_rep_get_ndev(oct, ifidx);
- if (!vf_ndev)
- goto free_buffers;
- vf_rep = netdev_priv(vf_ndev);
- if (!(atomic_read(&vf_rep->ifstate) & LIO_IFSTATE_RUNNING) ||
- recv_pkt->buffer_count > 1)
- goto free_buffers;
- skb->dev = vf_ndev;
- /* Multiple buffers are not used for vf_rep packets.
- * So just buffer_size[0] is valid.
- */
- lio_vf_rep_copy_packet(oct, skb, recv_pkt->buffer_size[0]);
- skb_pull(skb, rh->r_dh.len * BYTES_PER_DHLEN_UNIT);
- skb->protocol = eth_type_trans(skb, skb->dev);
- skb->ip_summed = CHECKSUM_NONE;
- netif_rx(skb);
- octeon_free_recv_info(recv_info);
- return 0;
- free_buffers:
- for (i = 0; i < recv_pkt->buffer_count; i++)
- recv_buffer_free(recv_pkt->buffer_ptr[i]);
- octeon_free_recv_info(recv_info);
- return 0;
- }
- static void
- lio_vf_rep_packet_sent_callback(struct octeon_device *oct,
- u32 status, void *buf)
- {
- struct octeon_soft_command *sc = (struct octeon_soft_command *)buf;
- struct sk_buff *skb = sc->ctxptr;
- struct net_device *ndev = skb->dev;
- u32 iq_no;
- dma_unmap_single(&oct->pci_dev->dev, sc->dmadptr,
- sc->datasize, DMA_TO_DEVICE);
- dev_kfree_skb_any(skb);
- iq_no = sc->iq_no;
- octeon_free_soft_command(oct, sc);
- if (octnet_iq_is_full(oct, iq_no))
- return;
- if (netif_queue_stopped(ndev))
- netif_wake_queue(ndev);
- }
- static netdev_tx_t
- lio_vf_rep_pkt_xmit(struct sk_buff *skb, struct net_device *ndev)
- {
- struct lio_vf_rep_desc *vf_rep = netdev_priv(ndev);
- struct net_device *parent_ndev = vf_rep->parent_ndev;
- struct octeon_device *oct = vf_rep->oct;
- struct octeon_instr_pki_ih3 *pki_ih3;
- struct octeon_soft_command *sc;
- struct lio *parent_lio;
- int status;
- parent_lio = GET_LIO(parent_ndev);
- if (!(atomic_read(&vf_rep->ifstate) & LIO_IFSTATE_RUNNING) ||
- skb->len <= 0)
- goto xmit_failed;
- if (octnet_iq_is_full(vf_rep->oct, parent_lio->txq)) {
- dev_err(&oct->pci_dev->dev, "VF rep: Device IQ full\n");
- netif_stop_queue(ndev);
- return NETDEV_TX_BUSY;
- }
- sc = (struct octeon_soft_command *)
- octeon_alloc_soft_command(oct, 0, 0, 0);
- if (!sc) {
- dev_err(&oct->pci_dev->dev, "VF rep: Soft command alloc failed\n");
- goto xmit_failed;
- }
- /* Multiple buffers are not used for vf_rep packets. */
- if (skb_shinfo(skb)->nr_frags != 0) {
- dev_err(&oct->pci_dev->dev, "VF rep: nr_frags != 0. Dropping packet\n");
- goto xmit_failed;
- }
- sc->dmadptr = dma_map_single(&oct->pci_dev->dev,
- skb->data, skb->len, DMA_TO_DEVICE);
- if (dma_mapping_error(&oct->pci_dev->dev, sc->dmadptr)) {
- dev_err(&oct->pci_dev->dev, "VF rep: DMA mapping failed\n");
- goto xmit_failed;
- }
- sc->virtdptr = skb->data;
- sc->datasize = skb->len;
- sc->ctxptr = skb;
- sc->iq_no = parent_lio->txq;
- octeon_prepare_soft_command(oct, sc, OPCODE_NIC, OPCODE_NIC_VF_REP_PKT,
- vf_rep->ifidx, 0, 0);
- pki_ih3 = (struct octeon_instr_pki_ih3 *)&sc->cmd.cmd3.pki_ih3;
- pki_ih3->tagtype = ORDERED_TAG;
- sc->callback = lio_vf_rep_packet_sent_callback;
- sc->callback_arg = sc;
- status = octeon_send_soft_command(oct, sc);
- if (status == IQ_SEND_FAILED) {
- dma_unmap_single(&oct->pci_dev->dev, sc->dmadptr,
- sc->datasize, DMA_TO_DEVICE);
- goto xmit_failed;
- }
- if (status == IQ_SEND_STOP)
- netif_stop_queue(ndev);
- netif_trans_update(ndev);
- return NETDEV_TX_OK;
- xmit_failed:
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
- static int
- lio_vf_rep_attr_get(struct net_device *dev, struct switchdev_attr *attr)
- {
- struct lio_vf_rep_desc *vf_rep = netdev_priv(dev);
- struct net_device *parent_ndev = vf_rep->parent_ndev;
- struct lio *lio = GET_LIO(parent_ndev);
- switch (attr->id) {
- case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
- attr->u.ppid.id_len = ETH_ALEN;
- ether_addr_copy(attr->u.ppid.id,
- (void *)&lio->linfo.hw_addr + 2);
- break;
- default:
- return -EOPNOTSUPP;
- }
- return 0;
- }
- static const struct switchdev_ops lio_vf_rep_switchdev_ops = {
- .switchdev_port_attr_get = lio_vf_rep_attr_get,
- };
- static void
- lio_vf_rep_fetch_stats(struct work_struct *work)
- {
- struct cavium_wk *wk = (struct cavium_wk *)work;
- struct lio_vf_rep_desc *vf_rep = wk->ctxptr;
- struct lio_vf_rep_stats stats;
- struct lio_vf_rep_req rep_cfg;
- struct octeon_device *oct;
- int ret;
- oct = vf_rep->oct;
- memset(&rep_cfg, 0, sizeof(rep_cfg));
- rep_cfg.req_type = LIO_VF_REP_REQ_STATS;
- rep_cfg.ifidx = vf_rep->ifidx;
- ret = lio_vf_rep_send_soft_command(oct, &rep_cfg, sizeof(rep_cfg),
- &stats, sizeof(stats));
- if (!ret) {
- octeon_swap_8B_data((u64 *)&stats, (sizeof(stats) >> 3));
- memcpy(&vf_rep->stats, &stats, sizeof(stats));
- }
- schedule_delayed_work(&vf_rep->stats_wk.work,
- msecs_to_jiffies(LIO_VF_REP_STATS_POLL_TIME_MS));
- }
- int
- lio_vf_rep_create(struct octeon_device *oct)
- {
- struct lio_vf_rep_desc *vf_rep;
- struct net_device *ndev;
- int i, num_vfs;
- if (oct->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
- return 0;
- if (!oct->sriov_info.sriov_enabled)
- return 0;
- num_vfs = oct->sriov_info.num_vfs_alloced;
- oct->vf_rep_list.num_vfs = 0;
- for (i = 0; i < num_vfs; i++) {
- ndev = alloc_etherdev(sizeof(struct lio_vf_rep_desc));
- if (!ndev) {
- dev_err(&oct->pci_dev->dev,
- "VF rep device %d creation failed\n", i);
- goto cleanup;
- }
- ndev->min_mtu = LIO_MIN_MTU_SIZE;
- ndev->max_mtu = LIO_MAX_MTU_SIZE;
- ndev->netdev_ops = &lio_vf_rep_ndev_ops;
- SWITCHDEV_SET_OPS(ndev, &lio_vf_rep_switchdev_ops);
- vf_rep = netdev_priv(ndev);
- memset(vf_rep, 0, sizeof(*vf_rep));
- vf_rep->ndev = ndev;
- vf_rep->oct = oct;
- vf_rep->parent_ndev = oct->props[0].netdev;
- vf_rep->ifidx = (oct->pf_num * 64) + i + 1;
- eth_hw_addr_random(ndev);
- if (register_netdev(ndev)) {
- dev_err(&oct->pci_dev->dev, "VF rep nerdev registration failed\n");
- free_netdev(ndev);
- goto cleanup;
- }
- netif_carrier_off(ndev);
- INIT_DELAYED_WORK(&vf_rep->stats_wk.work,
- lio_vf_rep_fetch_stats);
- vf_rep->stats_wk.ctxptr = (void *)vf_rep;
- schedule_delayed_work(&vf_rep->stats_wk.work,
- msecs_to_jiffies
- (LIO_VF_REP_STATS_POLL_TIME_MS));
- oct->vf_rep_list.num_vfs++;
- oct->vf_rep_list.ndev[i] = ndev;
- }
- if (octeon_register_dispatch_fn(oct, OPCODE_NIC,
- OPCODE_NIC_VF_REP_PKT,
- lio_vf_rep_pkt_recv, oct)) {
- dev_err(&oct->pci_dev->dev, "VF rep Dispatch func registration failed\n");
- goto cleanup;
- }
- return 0;
- cleanup:
- for (i = 0; i < oct->vf_rep_list.num_vfs; i++) {
- ndev = oct->vf_rep_list.ndev[i];
- oct->vf_rep_list.ndev[i] = NULL;
- if (ndev) {
- vf_rep = netdev_priv(ndev);
- cancel_delayed_work_sync
- (&vf_rep->stats_wk.work);
- unregister_netdev(ndev);
- free_netdev(ndev);
- }
- }
- oct->vf_rep_list.num_vfs = 0;
- return -1;
- }
- void
- lio_vf_rep_destroy(struct octeon_device *oct)
- {
- struct lio_vf_rep_desc *vf_rep;
- struct net_device *ndev;
- int i;
- if (oct->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
- return;
- if (!oct->sriov_info.sriov_enabled)
- return;
- for (i = 0; i < oct->vf_rep_list.num_vfs; i++) {
- ndev = oct->vf_rep_list.ndev[i];
- oct->vf_rep_list.ndev[i] = NULL;
- if (ndev) {
- vf_rep = netdev_priv(ndev);
- cancel_delayed_work_sync
- (&vf_rep->stats_wk.work);
- netif_tx_disable(ndev);
- netif_carrier_off(ndev);
- unregister_netdev(ndev);
- free_netdev(ndev);
- }
- }
- oct->vf_rep_list.num_vfs = 0;
- }
- static int
- lio_vf_rep_netdev_event(struct notifier_block *nb,
- unsigned long event, void *ptr)
- {
- struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
- struct lio_vf_rep_desc *vf_rep;
- struct lio_vf_rep_req rep_cfg;
- struct octeon_device *oct;
- int ret;
- switch (event) {
- case NETDEV_REGISTER:
- case NETDEV_CHANGENAME:
- break;
- default:
- return NOTIFY_DONE;
- }
- if (ndev->netdev_ops != &lio_vf_rep_ndev_ops)
- return NOTIFY_DONE;
- vf_rep = netdev_priv(ndev);
- oct = vf_rep->oct;
- if (strlen(ndev->name) > LIO_IF_NAME_SIZE) {
- dev_err(&oct->pci_dev->dev,
- "Device name change sync failed as the size is > %d\n",
- LIO_IF_NAME_SIZE);
- return NOTIFY_DONE;
- }
- memset(&rep_cfg, 0, sizeof(rep_cfg));
- rep_cfg.req_type = LIO_VF_REP_REQ_DEVNAME;
- rep_cfg.ifidx = vf_rep->ifidx;
- strncpy(rep_cfg.rep_name.name, ndev->name, LIO_IF_NAME_SIZE);
- ret = lio_vf_rep_send_soft_command(oct, &rep_cfg,
- sizeof(rep_cfg), NULL, 0);
- if (ret)
- dev_err(&oct->pci_dev->dev,
- "vf_rep netdev name change failed with err %d\n", ret);
- return NOTIFY_DONE;
- }
- static struct notifier_block lio_vf_rep_netdev_notifier = {
- .notifier_call = lio_vf_rep_netdev_event,
- };
- int
- lio_vf_rep_modinit(void)
- {
- if (register_netdevice_notifier(&lio_vf_rep_netdev_notifier)) {
- pr_err("netdev notifier registration failed\n");
- return -EFAULT;
- }
- return 0;
- }
- void
- lio_vf_rep_modexit(void)
- {
- if (unregister_netdevice_notifier(&lio_vf_rep_netdev_notifier))
- pr_err("netdev notifier unregister failed\n");
- }
|