Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 208c6b9a authored by WingMan Kwok's avatar WingMan Kwok Committed by David S. Miller
Browse files

net: netcp: Fixes error in oversized memory allocation for statistics storage



The CPSW driver keeps internally some, but not all, of
the statistics available in the hw statistics modules.  Furthermore,
some of the locations in the hw statistics modules are reserved and
contain no useful information.  Prior to this patch, the driver
allocates memory of the size of the the whole hw statistics modules,
instead of the size of statistics-entries-interested-in (i.e. et_stats),
for internal storage.  This patch fixes that.

Signed-off-by: default avatarWingMan Kwok <w-kwok2@ti.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a94bcd09
Loading
Loading
Loading
Loading
+21 −25
Original line number Original line Diff line number Diff line
@@ -295,8 +295,6 @@ struct xgbe_hw_stats {
	u32	rx_dma_overruns;
	u32	rx_dma_overruns;
};
};


#define XGBE10_NUM_STAT_ENTRIES (sizeof(struct xgbe_hw_stats)/sizeof(u32))

struct gbenu_ss_regs {
struct gbenu_ss_regs {
	u32	id_ver;
	u32	id_ver;
	u32	synce_count;		/* NU */
	u32	synce_count;		/* NU */
@@ -480,7 +478,6 @@ struct gbenu_hw_stats {
	u32	tx_pri7_drop_bcnt;
	u32	tx_pri7_drop_bcnt;
};
};


#define GBENU_NUM_HW_STAT_ENTRIES (sizeof(struct gbenu_hw_stats) / sizeof(u32))
#define GBENU_HW_STATS_REG_MAP_SZ	0x200
#define GBENU_HW_STATS_REG_MAP_SZ	0x200


struct gbe_ss_regs {
struct gbe_ss_regs {
@@ -615,7 +612,6 @@ struct gbe_hw_stats {
	u32	rx_dma_overruns;
	u32	rx_dma_overruns;
};
};


#define GBE13_NUM_HW_STAT_ENTRIES (sizeof(struct gbe_hw_stats)/sizeof(u32))
#define GBE_MAX_HW_STAT_MODS			9
#define GBE_MAX_HW_STAT_MODS			9
#define GBE_HW_STATS_REG_MAP_SZ			0x100
#define GBE_HW_STATS_REG_MAP_SZ			0x100


@@ -2555,9 +2551,11 @@ static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev,
	}
	}
	gbe_dev->xgbe_serdes_regs = regs;
	gbe_dev->xgbe_serdes_regs = regs;


	gbe_dev->et_stats = xgbe10_et_stats;
	gbe_dev->num_et_stats = ARRAY_SIZE(xgbe10_et_stats);

	gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev,
	gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev,
				  XGBE10_NUM_STAT_ENTRIES *
					 gbe_dev->num_et_stats * sizeof(u64),
				  (gbe_dev->max_num_ports) * sizeof(u64),
					 GFP_KERNEL);
					 GFP_KERNEL);
	if (!gbe_dev->hw_stats) {
	if (!gbe_dev->hw_stats) {
		dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n");
		dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n");
@@ -2577,8 +2575,6 @@ static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev,
	gbe_dev->ale_ports = gbe_dev->max_num_ports;
	gbe_dev->ale_ports = gbe_dev->max_num_ports;
	gbe_dev->host_port = XGBE10_HOST_PORT_NUM;
	gbe_dev->host_port = XGBE10_HOST_PORT_NUM;
	gbe_dev->ale_entries = XGBE10_NUM_ALE_ENTRIES;
	gbe_dev->ale_entries = XGBE10_NUM_ALE_ENTRIES;
	gbe_dev->et_stats = xgbe10_et_stats;
	gbe_dev->num_et_stats = ARRAY_SIZE(xgbe10_et_stats);
	gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1;
	gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1;


	/* Subsystem registers */
	/* Subsystem registers */
@@ -2663,9 +2659,11 @@ static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev,
	}
	}
	gbe_dev->switch_regs = regs;
	gbe_dev->switch_regs = regs;


	gbe_dev->et_stats = gbe13_et_stats;
	gbe_dev->num_et_stats = ARRAY_SIZE(gbe13_et_stats);

	gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev,
	gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev,
					  GBE13_NUM_HW_STAT_ENTRIES *
					 gbe_dev->num_et_stats * sizeof(u64),
					  gbe_dev->max_num_slaves * sizeof(u64),
					 GFP_KERNEL);
					 GFP_KERNEL);
	if (!gbe_dev->hw_stats) {
	if (!gbe_dev->hw_stats) {
		dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n");
		dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n");
@@ -2689,8 +2687,6 @@ static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev,
	gbe_dev->ale_ports = gbe_dev->max_num_ports;
	gbe_dev->ale_ports = gbe_dev->max_num_ports;
	gbe_dev->host_port = GBE13_HOST_PORT_NUM;
	gbe_dev->host_port = GBE13_HOST_PORT_NUM;
	gbe_dev->ale_entries = GBE13_NUM_ALE_ENTRIES;
	gbe_dev->ale_entries = GBE13_NUM_ALE_ENTRIES;
	gbe_dev->et_stats = gbe13_et_stats;
	gbe_dev->num_et_stats = ARRAY_SIZE(gbe13_et_stats);
	gbe_dev->stats_en_mask = GBE13_REG_VAL_STAT_ENABLE_ALL;
	gbe_dev->stats_en_mask = GBE13_REG_VAL_STAT_ENABLE_ALL;


	/* Subsystem registers */
	/* Subsystem registers */
@@ -2717,9 +2713,17 @@ static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev,
	void __iomem *regs;
	void __iomem *regs;
	int i, ret;
	int i, ret;


	gbe_dev->et_stats = gbenu_et_stats;

	if (IS_SS_ID_NU(gbe_dev))
		gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE +
			(gbe_dev->max_num_slaves * GBENU_ET_STATS_PORT_SIZE);
	else
		gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE +
					GBENU_ET_STATS_PORT_SIZE;

	gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev,
	gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev,
				  GBENU_NUM_HW_STAT_ENTRIES *
					 gbe_dev->num_et_stats * sizeof(u64),
				  (gbe_dev->max_num_ports) * sizeof(u64),
					 GFP_KERNEL);
					 GFP_KERNEL);
	if (!gbe_dev->hw_stats) {
	if (!gbe_dev->hw_stats) {
		dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n");
		dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n");
@@ -2753,16 +2757,8 @@ static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev,
	gbe_dev->ale_ports = gbe_dev->max_num_ports;
	gbe_dev->ale_ports = gbe_dev->max_num_ports;
	gbe_dev->host_port = GBENU_HOST_PORT_NUM;
	gbe_dev->host_port = GBENU_HOST_PORT_NUM;
	gbe_dev->ale_entries = GBE13_NUM_ALE_ENTRIES;
	gbe_dev->ale_entries = GBE13_NUM_ALE_ENTRIES;
	gbe_dev->et_stats = gbenu_et_stats;
	gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1;
	gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1;


	if (IS_SS_ID_NU(gbe_dev))
		gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE +
			(gbe_dev->max_num_slaves * GBENU_ET_STATS_PORT_SIZE);
	else
		gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE +
					GBENU_ET_STATS_PORT_SIZE;

	/* Subsystem registers */
	/* Subsystem registers */
	GBENU_SET_REG_OFS(gbe_dev, ss_regs, id_ver);
	GBENU_SET_REG_OFS(gbe_dev, ss_regs, id_ver);