ethtool: Centralise validation of ETHTOOL_{G, S}RXFHINDIR parameters
[deliverable/linux.git] / drivers / net / ethernet / broadcom / bnx2x / bnx2x_ethtool.c
index f0ca8b27a55eea7b96f3984b03aaead457ba3db8..a688b9d975a2576f5285417d3a23ed53a5c3fb5b 100644 (file)
@@ -107,6 +107,10 @@ static const struct {
                                4, STATS_FLAGS_PORT, "rx_filtered_packets" },
        { STATS_OFFSET32(mf_tag_discard),
                                4, STATS_FLAGS_PORT, "rx_mf_tag_discard" },
+       { STATS_OFFSET32(pfc_frames_received_hi),
+                               8, STATS_FLAGS_PORT, "pfc_frames_received" },
+       { STATS_OFFSET32(pfc_frames_sent_hi),
+                               8, STATS_FLAGS_PORT, "pfc_frames_sent" },
        { STATS_OFFSET32(brb_drop_hi),
                                8, STATS_FLAGS_PORT, "rx_brb_discard" },
        { STATS_OFFSET32(brb_truncate_hi),
@@ -352,7 +356,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                DP(NETIF_MSG_LINK, "Unsupported port type\n");
                return -EINVAL;
        }
-       /* Save new config in case command complete successuly */
+       /* Save new config in case command complete successully */
        new_multi_phy_config = bp->link_params.multi_phy_config;
        /* Get the new cfg_idx */
        cfg_idx = bnx2x_get_link_cfg_idx(bp);
@@ -761,8 +765,8 @@ static void bnx2x_get_drvinfo(struct net_device *dev,
        struct bnx2x *bp = netdev_priv(dev);
        u8 phy_fw_ver[PHY_FW_VER_LEN];
 
-       strcpy(info->driver, DRV_MODULE_NAME);
-       strcpy(info->version, DRV_MODULE_VERSION);
+       strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
+       strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
 
        phy_fw_ver[0] = '\0';
        if (bp->port.pmf) {
@@ -773,14 +777,14 @@ static void bnx2x_get_drvinfo(struct net_device *dev,
                bnx2x_release_phy_lock(bp);
        }
 
-       strncpy(info->fw_version, bp->fw_ver, 32);
+       strlcpy(info->fw_version, bp->fw_ver, sizeof(info->fw_version));
        snprintf(info->fw_version + strlen(bp->fw_ver), 32 - strlen(bp->fw_ver),
                 "bc %d.%d.%d%s%s",
                 (bp->common.bc_ver & 0xff0000) >> 16,
                 (bp->common.bc_ver & 0xff00) >> 8,
                 (bp->common.bc_ver & 0xff),
                 ((phy_fw_ver[0] != '\0') ? " phy " : ""), phy_fw_ver);
-       strcpy(info->bus_info, pci_name(bp->pdev));
+       strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info));
        info->n_stats = BNX2X_NUM_STATS;
        info->testinfo_len = BNX2X_NUM_TESTS;
        info->eedump_len = bp->common.flash_size;
@@ -1740,6 +1744,8 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode)
        struct sw_rx_bd *rx_buf;
        u16 len;
        int rc = -ENODEV;
+       u8 *data;
+       struct netdev_queue *txq = netdev_get_tx_queue(bp->dev, txdata->txq_index);
 
        /* check the loopback mode */
        switch (loopback_mode) {
@@ -1748,8 +1754,18 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode)
                        return -EINVAL;
                break;
        case BNX2X_MAC_LOOPBACK:
-               bp->link_params.loopback_mode = CHIP_IS_E3(bp) ?
-                                               LOOPBACK_XMAC : LOOPBACK_BMAC;
+               if (CHIP_IS_E3(bp)) {
+                       int cfg_idx = bnx2x_get_link_cfg_idx(bp);
+                       if (bp->port.supported[cfg_idx] &
+                           (SUPPORTED_10000baseT_Full |
+                            SUPPORTED_20000baseMLD2_Full |
+                            SUPPORTED_20000baseKR2_Full))
+                               bp->link_params.loopback_mode = LOOPBACK_XMAC;
+                       else
+                               bp->link_params.loopback_mode = LOOPBACK_UMAC;
+               } else
+                       bp->link_params.loopback_mode = LOOPBACK_BMAC;
+
                bnx2x_phy_init(&bp->link_params, &bp->link_vars);
                break;
        default:
@@ -1784,6 +1800,8 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode)
        tx_start_idx = le16_to_cpu(*txdata->tx_cons_sb);
        rx_start_idx = le16_to_cpu(*fp_rx->rx_cons_sb);
 
+       netdev_tx_sent_queue(txq, skb->len);
+
        pkt_prod = txdata->tx_pkt_prod++;
        tx_buf = &txdata->tx_buf_ring[TX_BD(pkt_prod)];
        tx_buf->first_bd = txdata->tx_bd_prod;
@@ -1865,10 +1883,9 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode)
        dma_sync_single_for_cpu(&bp->pdev->dev,
                                   dma_unmap_addr(rx_buf, mapping),
                                   fp_rx->rx_buf_size, DMA_FROM_DEVICE);
-       skb = rx_buf->skb;
-       skb_reserve(skb, cqe->fast_path_cqe.placement_offset);
+       data = rx_buf->data + NET_SKB_PAD + cqe->fast_path_cqe.placement_offset;
        for (i = ETH_HLEN; i < pkt_size; i++)
-               if (*(skb->data + i) != (unsigned char) (i & 0xff))
+               if (*(data + i) != (unsigned char) (i & 0xff))
                        goto test_loopback_rx_exit;
 
        rc = 0;
@@ -2285,18 +2302,20 @@ static int bnx2x_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
        }
 }
 
-static int bnx2x_get_rxfh_indir(struct net_device *dev,
-                               struct ethtool_rxfh_indir *indir)
+static u32 bnx2x_get_rxfh_indir_size(struct net_device *dev)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       return (bp->multi_mode == ETH_RSS_MODE_DISABLED ?
+               0 : T_ETH_INDIRECTION_TABLE_SIZE);
+}
+
+static int bnx2x_get_rxfh_indir(struct net_device *dev, u32 *indir)
 {
        struct bnx2x *bp = netdev_priv(dev);
-       size_t copy_size =
-               min_t(size_t, indir->size, T_ETH_INDIRECTION_TABLE_SIZE);
        u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE] = {0};
        size_t i;
 
-       if (bp->multi_mode == ETH_RSS_MODE_DISABLED)
-               return -EOPNOTSUPP;
-
        /* Get the current configuration of the RSS indirection table */
        bnx2x_get_rss_ind_table(&bp->rss_conf_obj, ind_table);
 
@@ -2309,33 +2328,19 @@ static int bnx2x_get_rxfh_indir(struct net_device *dev,
         * align the returned table to the Client ID of the leading RSS
         * queue.
         */
-       for (i = 0; i < copy_size; i++)
-               indir->ring_index[i] = ind_table[i] - bp->fp->cl_id;
-
-       indir->size = T_ETH_INDIRECTION_TABLE_SIZE;
+       for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++)
+               indir[i] = ind_table[i] - bp->fp->cl_id;
 
        return 0;
 }
 
-static int bnx2x_set_rxfh_indir(struct net_device *dev,
-                               const struct ethtool_rxfh_indir *indir)
+static int bnx2x_set_rxfh_indir(struct net_device *dev, const u32 *indir)
 {
        struct bnx2x *bp = netdev_priv(dev);
        size_t i;
        u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE] = {0};
-       u32 num_eth_queues = BNX2X_NUM_ETH_QUEUES(bp);
-
-       if (bp->multi_mode == ETH_RSS_MODE_DISABLED)
-               return -EOPNOTSUPP;
-
-       /* validate the size */
-       if (indir->size != T_ETH_INDIRECTION_TABLE_SIZE)
-               return -EINVAL;
 
        for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++) {
-               /* validate the indices */
-               if (indir->ring_index[i] >= num_eth_queues)
-                       return -EINVAL;
                /*
                 * The same as in bnx2x_get_rxfh_indir: we can't use a memcpy()
                 * as an internal storage of an indirection table is a u8 array
@@ -2345,7 +2350,7 @@ static int bnx2x_set_rxfh_indir(struct net_device *dev,
                 * align the received table to the Client ID of the leading RSS
                 * queue
                 */
-               ind_table[i] = indir->ring_index[i] + bp->fp->cl_id;
+               ind_table[i] = indir[i] + bp->fp->cl_id;
        }
 
        return bnx2x_config_rss_pf(bp, ind_table, false);
@@ -2378,6 +2383,7 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
        .set_phys_id            = bnx2x_set_phys_id,
        .get_ethtool_stats      = bnx2x_get_ethtool_stats,
        .get_rxnfc              = bnx2x_get_rxnfc,
+       .get_rxfh_indir_size    = bnx2x_get_rxfh_indir_size,
        .get_rxfh_indir         = bnx2x_get_rxfh_indir,
        .set_rxfh_indir         = bnx2x_set_rxfh_indir,
 };
This page took 0.030253 seconds and 5 git commands to generate.