Commit 20862788 authored by Claudiu Manoil's avatar Claudiu Manoil Committed by David S. Miller

gianfar: Cleanup/Fix gfar_probe and the hw init code

Factor out gfar_hw_init() to contain all the controller hw
initialization steps for a better control of register writes,
and to significantly simplify the tangled code from gfar_probe().
This results in code size and stack usage reduction (besides
code readability).

Fix memory leak on device removal, by freeing the rx_/tx_queue

Replace custom bit swapping function with a library one (bitrev8).

Move allocation of rx_/tx_queue struct arrays before the group
structure init, because in order to assign Rx/Tx queues
to groups we need to have the queues first.  This also allows
earlier bail out of gfar_probe(), in case the memory allocation

The flow control checks for maccfg1 were removed from gfar_probe(),
since flow control is disabled at probe time (priv->rx_/tx_pause_en
are 0). Redundant initializations (by 0) also removed.
Signed-off-by: default avatarClaudiu Manoil <>
Signed-off-by: default avatarDavid S. Miller <>
parent c85fde83
This diff is collapsed.
......@@ -9,7 +9,7 @@
* Maintainer: Kumar Gala
* Modifier: Sandeep Gopalpet <>
* Copyright 2002-2009, 2011 Freescale Semiconductor, Inc.
* Copyright 2002-2009, 2011-2013 Freescale Semiconductor, Inc.
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
......@@ -892,8 +892,8 @@ struct gfar {
#define ISRG_SHIFT_TX 0x10
#define ISRG_SHIFT_RX 0x18
#define ISRG_RR0 0x80000000
#define ISRG_TR0 0x00800000
/* The same driver can operate in two modes */
/* SQ_SG_MODE: Single Queue Single Group Mode
......@@ -1113,6 +1113,9 @@ struct gfar_private {
unsigned int total_tx_ring_size;
unsigned int total_rx_ring_size;
u32 rqueue;
u32 tqueue;
/* RX per device parameters */
unsigned int rx_stash_size;
unsigned int rx_stash_index;
......@@ -1176,6 +1179,31 @@ static inline void gfar_read_filer(struct gfar_private *priv,
*fpr = gfar_read(&regs->rqfpr);
static inline void gfar_write_isrg(struct gfar_private *priv)
struct gfar __iomem *regs = priv->gfargrp[0].regs;
u32 __iomem *baddr = &regs->isrg0;
u32 isrg = 0;
int grp_idx, i;
for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) {
struct gfar_priv_grp *grp = &priv->gfargrp[grp_idx];
for_each_set_bit(i, &grp->rx_bit_map, priv->num_rx_queues) {
isrg |= (ISRG_RR0 >> i);
for_each_set_bit(i, &grp->tx_bit_map, priv->num_tx_queues) {
isrg |= (ISRG_TR0 >> i);
gfar_write(baddr, isrg);
isrg = 0;
void lock_rx_qs(struct gfar_private *priv);
void lock_tx_qs(struct gfar_private *priv);
void unlock_rx_qs(struct gfar_private *priv);
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment