qede: Fix out-of-bound fastpath memory access
[cascardo/linux.git] / drivers / net / ethernet / qlogic / qede / qede_main.c
index 0e198fe..7def29a 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/random.h>
 #include <net/ip6_checksum.h>
 #include <linux/bitops.h>
-
+#include <linux/qed/qede_roce.h>
 #include "qede.h"
 
 static char version[] =
@@ -193,8 +193,7 @@ static int qede_netdev_event(struct notifier_block *this, unsigned long event,
        struct ethtool_drvinfo drvinfo;
        struct qede_dev *edev;
 
-       /* Currently only support name change */
-       if (event != NETDEV_CHANGENAME)
+       if (event != NETDEV_CHANGENAME && event != NETDEV_CHANGEADDR)
                goto done;
 
        /* Check whether this is a qede device */
@@ -207,11 +206,18 @@ static int qede_netdev_event(struct notifier_block *this, unsigned long event,
                goto done;
        edev = netdev_priv(ndev);
 
-       /* Notify qed of the name change */
-       if (!edev->ops || !edev->ops->common)
-               goto done;
-       edev->ops->common->set_id(edev->cdev, edev->ndev->name,
-                                 "qede");
+       switch (event) {
+       case NETDEV_CHANGENAME:
+               /* Notify qed of the name change */
+               if (!edev->ops || !edev->ops->common)
+                       goto done;
+               edev->ops->common->set_id(edev->cdev, edev->ndev->name, "qede");
+               break;
+       case NETDEV_CHANGEADDR:
+               edev = netdev_priv(ndev);
+               qede_roce_event_changeaddr(edev);
+               break;
+       }
 
 done:
        return NOTIFY_DONE;
@@ -307,8 +313,8 @@ static int qede_free_tx_pkt(struct qede_dev *edev,
                split_bd_len = BD_UNMAP_LEN(split);
                bds_consumed++;
        }
-       dma_unmap_page(&edev->pdev->dev, BD_UNMAP_ADDR(first_bd),
-                      BD_UNMAP_LEN(first_bd) + split_bd_len, DMA_TO_DEVICE);
+       dma_unmap_single(&edev->pdev->dev, BD_UNMAP_ADDR(first_bd),
+                        BD_UNMAP_LEN(first_bd) + split_bd_len, DMA_TO_DEVICE);
 
        /* Unmap the data of the skb frags */
        for (i = 0; i < skb_shinfo(skb)->nr_frags; i++, bds_consumed++) {
@@ -353,8 +359,8 @@ static void qede_free_failed_tx_pkt(struct qede_dev *edev,
                nbd--;
        }
 
-       dma_unmap_page(&edev->pdev->dev, BD_UNMAP_ADDR(first_bd),
-                      BD_UNMAP_LEN(first_bd) + split_bd_len, DMA_TO_DEVICE);
+       dma_unmap_single(&edev->pdev->dev, BD_UNMAP_ADDR(first_bd),
+                        BD_UNMAP_LEN(first_bd) + split_bd_len, DMA_TO_DEVICE);
 
        /* Unmap the data of the skb frags */
        for (i = 0; i < nbd; i++) {
@@ -937,8 +943,7 @@ static inline int qede_realloc_rx_buffer(struct qede_dev *edev,
        return 0;
 }
 
-static inline void qede_update_rx_prod(struct qede_dev *edev,
-                                      struct qede_rx_queue *rxq)
+void qede_update_rx_prod(struct qede_dev *edev, struct qede_rx_queue *rxq)
 {
        u16 bd_prod = qed_chain_get_prod_idx(&rxq->rx_bd_ring);
        u16 cqe_prod = qed_chain_get_prod_idx(&rxq->rx_comp_ring);
@@ -2545,10 +2550,14 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
 
        qede_init_ndev(edev);
 
+       rc = qede_roce_dev_add(edev);
+       if (rc)
+               goto err3;
+
        rc = register_netdev(edev->ndev);
        if (rc) {
                DP_NOTICE(edev, "Cannot register net-device\n");
-               goto err3;
+               goto err4;
        }
 
        edev->ops->common->set_id(cdev, edev->ndev->name, DRV_MODULE_VERSION);
@@ -2568,6 +2577,8 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
 
        return 0;
 
+err4:
+       qede_roce_dev_remove(edev);
 err3:
        free_netdev(edev->ndev);
 err2:
@@ -2614,8 +2625,11 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode)
        DP_INFO(edev, "Starting qede_remove\n");
 
        cancel_delayed_work_sync(&edev->sp_task);
+
        unregister_netdev(ndev);
 
+       qede_roce_dev_remove(edev);
+
        edev->ops->common->set_power_state(cdev, PCI_D0);
 
        pci_set_drvdata(pdev, NULL);
@@ -2926,7 +2940,7 @@ static int qede_alloc_mem_txq(struct qede_dev *edev, struct qede_tx_queue *txq)
        txq->num_tx_buffers = edev->q_num_tx_buffers;
 
        /* Allocate the parallel driver ring for Tx buffers */
-       size = sizeof(*txq->sw_tx_ring) * NUM_TX_BDS_MAX;
+       size = sizeof(*txq->sw_tx_ring) * TX_RING_SIZE;
        txq->sw_tx_ring = kzalloc(size, GFP_KERNEL);
        if (!txq->sw_tx_ring) {
                DP_NOTICE(edev, "Tx buffers ring allocation failed\n");
@@ -2937,7 +2951,7 @@ static int qede_alloc_mem_txq(struct qede_dev *edev, struct qede_tx_queue *txq)
                                            QED_CHAIN_USE_TO_CONSUME_PRODUCE,
                                            QED_CHAIN_MODE_PBL,
                                            QED_CHAIN_CNT_TYPE_U16,
-                                           NUM_TX_BDS_MAX,
+                                           TX_RING_SIZE,
                                            sizeof(*p_virt), &txq->tx_pbl);
        if (rc)
                goto err;
@@ -3512,6 +3526,7 @@ static void qede_unload(struct qede_dev *edev, enum qede_unload_mode mode)
 
        DP_INFO(edev, "Starting qede unload\n");
 
+       qede_roce_dev_event_close(edev);
        mutex_lock(&edev->qede_lock);
        edev->state = QEDE_STATE_CLOSED;
 
@@ -3612,6 +3627,7 @@ static int qede_load(struct qede_dev *edev, enum qede_load_mode mode)
        /* Query whether link is already-up */
        memset(&link_output, 0, sizeof(link_output));
        edev->ops->common->get_link(edev->cdev, &link_output);
+       qede_roce_dev_event_open(edev);
        qede_link_update(edev, &link_output);
 
        DP_INFO(edev, "Ending successfully qede load\n");