Netdev List
 help / color / mirror / Atom feed
* System Administrator Waarschuwing,
From: alexis.houdart @ 2011-09-30  8:39 UTC (permalink / raw)


System Administrator Waarschuwing,

Uw mailbox heeft overschreden de limiet van 20 GB, dat wordt

gedefinieerd
door je manager, u op dit moment op 20.9GB, zult u niet
in staat zijn om een nieuwe e-mail te sturen maakt of ontvangt
opnieuw tot bevestigt u uw mailbox.To revalideren uw
mailbox,
Klik en vul de link hieronder

==================>http://buzurl.com/bn83

Bedankt voor uw begrip

De beheerder van het systeem.

^ permalink raw reply

* How to use macvtap/macvlan correctly
From: Chris Webb @ 2011-09-30  8:49 UTC (permalink / raw)
  To: qemu-devel, netdev
In-Reply-To: <20100826114355.GA455@arachsys.com>

I'm trying to get bridge-mode communication between a macvtap and a host
macvlan working correctly, but I think I must be doing something wrong as
the host macvlan and guest macvtap apparently can't communicate. I'm aware
that the underlying eth0 interface can't communicate with the macvtap, but I
thought that creating a host macvlan device and configuring that was the
standard work-around?

On a clean host running linux 3.0.4 and iptables 2.6.39, with no networking
except lo up with 127.0.0.1/8, I did

  ip link add link eth0 name host address 02:a3:a6:ed:4b:94 type macvlan mode bridge
  ip addr add 10.0.0.3/24 dev host
  ip link set eth0 up
  ip link set host up

I can ping a second host 10.0.0.1 attached to the eth0 interface of the test
host without problem.

I then created a macvtap device and launched a qemu guest against it:

  ip link add link eth0 name macvtap0 type macvtap mode bridge
  qemu-kvm -nographic -kernel /boot/vmlinuz-guest \
    -append "console=ttyS0 root=/dev/vda" \
    -drive file=/tmp/testroot.img,if=virtio,cache=none \
    -net nic,model=virtio,macaddr=$(< /sys/class/net/macvtap0/address) \
    -net tap,fd=3 3<>/dev/tap$(< /sys/class/net/macvtap0/ifindex)

Configuring the eth0 inside the guest with 10.0.0.4/24, I discovered I can
ping the external machine, but not the host, despite the macvtap and macvlan
being in bridge mode.

  # ping 10.0.0.1
  PING 10.0.0.1 (10.0.0.1): 48 data bytes
  56 bytes from 10.0.0.1: icmp_seq=0 ttl=64 time=0.351 ms
  56 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.360 ms
  56 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.281 ms
  ^C--- 10.0.0.1 ping statistics ---
  3 packets transmitted, 3 packets received, 0% packet loss
  round-trip min/avg/max/stddev = 0.281/0.331/0.360/0.035 ms

  # ping 10.0.0.3
  PING 10.0.0.3 (10.0.0.3): 48 data bytes
  ^C--- 10.0.0.3 ping statistics ---
  3 packets transmitted, 0 packets received, 100% packet loss

However something is working, because inside the guest:

# ip neigh
10.0.0.1 dev eth0 lladdr c8:0a:a9:37:29:6a REACHABLE
10.0.0.3 dev eth0 lladdr 02:a3:a6:ed:4b:94 REACHABLE

...and the MAC address it has for 10.0.0.3 is correct, so somehow an arp
request and response has got out to the host and back.

The kernel has

CONFIG_MACVLAN=y
CONFIG_MACVTAP=y
[...]
CONFIG_BRIDGE_NETFILTER=y
CONFIG_BRIDGE_NF_EBTABLES=y
CONFIG_BRIDGE=y
CONFIG_BRIDGE_IGMP_SNOOPING=y

(I didn't know off the top of my head if the bridge options are needed for
macvlan/vtap bridge mode, but they're compiled in anyway just in case.)

Any guesses what I've missed here?

Cheers,

Chris.

^ permalink raw reply

* [PATCH next 0/7] Pull request for 'davem-next.misc' branch (#2)
From: Francois Romieu @ 2011-09-30 10:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, Michael Chan

Please pull from branch 'davem-next.misc' in repository

git://violet.fr.zoreil.com/romieu/linux davem-next.misc

to get the changes below.

Since first request:
- silence __devinit annotations warnings (bnx2)
- removed spurious eol space from modified line (iphase)

Original request:
I have tested (and fixed) the iphase driver changes with a pair of
back-to-back oc3 cards. The bnx2 firmware changes have been rebased
against -next as suggested by Michael Chan.

Distance from 'davem-next' (56fd49e399ce1d82200fad5b8924d4e35a587809)
---------------------------------------------------------------------

66cd4c84a6901f99f973ad5931ddcaed8a9f18c6
2c29dc5512d84374595896374484ed4e271d7b5b
044e981c9e6461b698322c185aebb8a6eb5e74e8
99d68bf70e9e371005ae8113409135a157b84440
40e078ed5586f289bd89eebc223205ac80d31605
c1dbbf703ebddf73f5a801f93fc594f1bf0113cb
39bc30d36989834ba5bebce6f50bf1f6328da512

Diffstat
--------

 drivers/atm/iphase.c                   |  265 ++++++++++++----------
 drivers/atm/iphase.h                   |  391 ++++++++++++++++----------------
 drivers/net/ethernet/amd/depca.h       |    2 -
 drivers/net/ethernet/broadcom/bnx2.c   |   67 ++++--
 drivers/net/ethernet/dec/tulip/de4x5.h |    2 -
 drivers/net/ethernet/jme.h             |    1 -
 drivers/net/ethernet/realtek/8139cp.c  |    5 -
 drivers/net/ethernet/realtek/sc92031.c |    8 +-
 drivers/net/ethernet/tehuti/tehuti.c   |    8 +-
 drivers/net/usb/rtl8150.c              |  111 ++++-----
 10 files changed, 431 insertions(+), 429 deletions(-)

Shortlog
--------

Francois Romieu (7):
      bnx2: don't request firmware when there's no userspace.
      8139cp : removal of headers.
      atm/iphase : removal of PCI space dereferences.
      sc92031: use standard #defines from mii.h.
      rtl8150: removal of forward declarations.
      drivers/net/ethernet: remove unused #define.
      tehuti: shorten PCI device table.

Patch
-----

diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index cb90f7a..3d0c2b0 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -818,127 +818,152 @@ static void ia_hw_type(IADEV *iadev) {
 
 }
 
-static void IaFrontEndIntr(IADEV *iadev) {
-  volatile IA_SUNI *suni;
-  volatile ia_mb25_t *mb25;
-  volatile suni_pm7345_t *suni_pm7345;
-
-  if(iadev->phy_type & FE_25MBIT_PHY) {
-     mb25 = (ia_mb25_t*)iadev->phy;
-     iadev->carrier_detect =  Boolean(mb25->mb25_intr_status & MB25_IS_GSB);
-  } else if (iadev->phy_type & FE_DS3_PHY) {
-     suni_pm7345 = (suni_pm7345_t *)iadev->phy;
-     /* clear FRMR interrupts */
-     (void) suni_pm7345->suni_ds3_frm_intr_stat; 
-     iadev->carrier_detect =  
-           Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV));
-  } else if (iadev->phy_type & FE_E3_PHY ) {
-     suni_pm7345 = (suni_pm7345_t *)iadev->phy;
-     (void) suni_pm7345->suni_e3_frm_maint_intr_ind;
-     iadev->carrier_detect =
-           Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat&SUNI_E3_LOS));
-  }
-  else { 
-     suni = (IA_SUNI *)iadev->phy;
-     (void) suni->suni_rsop_status;
-     iadev->carrier_detect = Boolean(!(suni->suni_rsop_status & SUNI_LOSV));
-  }
-  if (iadev->carrier_detect)
-    printk("IA: SUNI carrier detected\n");
-  else
-    printk("IA: SUNI carrier lost signal\n"); 
-  return;
+static u32 ia_phy_read32(struct iadev_priv *ia, unsigned int reg)
+{
+	return readl(ia->phy + (reg >> 2));
+}
+
+static void ia_phy_write32(struct iadev_priv *ia, unsigned int reg, u32 val)
+{
+	writel(val, ia->phy + (reg >> 2));
+}
+
+static void ia_frontend_intr(struct iadev_priv *iadev)
+{
+	u32 status;
+
+	if (iadev->phy_type & FE_25MBIT_PHY) {
+		status = ia_phy_read32(iadev, MB25_INTR_STATUS);
+		iadev->carrier_detect = (status & MB25_IS_GSB) ? 1 : 0;
+	} else if (iadev->phy_type & FE_DS3_PHY) {
+		ia_phy_read32(iadev, SUNI_DS3_FRM_INTR_STAT);
+		status = ia_phy_read32(iadev, SUNI_DS3_FRM_STAT);
+		iadev->carrier_detect = (status & SUNI_DS3_LOSV) ? 0 : 1;
+	} else if (iadev->phy_type & FE_E3_PHY) {
+		ia_phy_read32(iadev, SUNI_E3_FRM_MAINT_INTR_IND);
+		status = ia_phy_read32(iadev, SUNI_E3_FRM_FRAM_INTR_IND_STAT);
+		iadev->carrier_detect = (status & SUNI_E3_LOS) ? 0 : 1;
+	} else {
+		status = ia_phy_read32(iadev, SUNI_RSOP_STATUS);
+		iadev->carrier_detect = (status & SUNI_LOSV) ? 0 : 1;
+	}
+
+	printk(KERN_INFO "IA: SUNI carrier %s\n",
+		iadev->carrier_detect ? "detected" : "lost signal");
 }
 
-static void ia_mb25_init (IADEV *iadev)
+static void ia_mb25_init(struct iadev_priv *iadev)
 {
-   volatile ia_mb25_t  *mb25 = (ia_mb25_t*)iadev->phy;
 #if 0
    mb25->mb25_master_ctrl = MB25_MC_DRIC | MB25_MC_DREC | MB25_MC_ENABLED;
 #endif
-   mb25->mb25_master_ctrl = MB25_MC_DRIC | MB25_MC_DREC;
-   mb25->mb25_diag_control = 0;
-   /*
-    * Initialize carrier detect state
-    */
-   iadev->carrier_detect =  Boolean(mb25->mb25_intr_status & MB25_IS_GSB);
-   return;
-}                   
+	ia_phy_write32(iadev, MB25_MASTER_CTRL, MB25_MC_DRIC | MB25_MC_DREC);
+	ia_phy_write32(iadev, MB25_DIAG_CONTROL, 0);
+
+	iadev->carrier_detect =
+		(ia_phy_read32(iadev, MB25_INTR_STATUS) & MB25_IS_GSB) ? 1 : 0;
+}
 
-static void ia_suni_pm7345_init (IADEV *iadev)
+struct ia_reg {
+	u16 reg;
+	u16 val;
+};
+
+static void ia_phy_write(struct iadev_priv *iadev,
+			 const struct ia_reg *regs, int len)
 {
-   volatile suni_pm7345_t *suni_pm7345 = (suni_pm7345_t *)iadev->phy;
-   if (iadev->phy_type & FE_DS3_PHY)
-   {
-      iadev->carrier_detect = 
-          Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV)); 
-      suni_pm7345->suni_ds3_frm_intr_enbl = 0x17;
-      suni_pm7345->suni_ds3_frm_cfg = 1;
-      suni_pm7345->suni_ds3_tran_cfg = 1;
-      suni_pm7345->suni_config = 0;
-      suni_pm7345->suni_splr_cfg = 0;
-      suni_pm7345->suni_splt_cfg = 0;
-   }
-   else 
-   {
-      iadev->carrier_detect = 
-          Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat & SUNI_E3_LOS));
-      suni_pm7345->suni_e3_frm_fram_options = 0x4;
-      suni_pm7345->suni_e3_frm_maint_options = 0x20;
-      suni_pm7345->suni_e3_frm_fram_intr_enbl = 0x1d;
-      suni_pm7345->suni_e3_frm_maint_intr_enbl = 0x30;
-      suni_pm7345->suni_e3_tran_stat_diag_options = 0x0;
-      suni_pm7345->suni_e3_tran_fram_options = 0x1;
-      suni_pm7345->suni_config = SUNI_PM7345_E3ENBL;
-      suni_pm7345->suni_splr_cfg = 0x41;
-      suni_pm7345->suni_splt_cfg = 0x41;
-   } 
-   /*
-    * Enable RSOP loss of signal interrupt.
-    */
-   suni_pm7345->suni_intr_enbl = 0x28;
- 
-   /*
-    * Clear error counters
-    */
-   suni_pm7345->suni_id_reset = 0;
-
-   /*
-    * Clear "PMCTST" in master test register.
-    */
-   suni_pm7345->suni_master_test = 0;
-
-   suni_pm7345->suni_rxcp_ctrl = 0x2c;
-   suni_pm7345->suni_rxcp_fctrl = 0x81;
- 
-   suni_pm7345->suni_rxcp_idle_pat_h1 =
-   	suni_pm7345->suni_rxcp_idle_pat_h2 =
-   	suni_pm7345->suni_rxcp_idle_pat_h3 = 0;
-   suni_pm7345->suni_rxcp_idle_pat_h4 = 1;
- 
-   suni_pm7345->suni_rxcp_idle_mask_h1 = 0xff;
-   suni_pm7345->suni_rxcp_idle_mask_h2 = 0xff;
-   suni_pm7345->suni_rxcp_idle_mask_h3 = 0xff;
-   suni_pm7345->suni_rxcp_idle_mask_h4 = 0xfe;
- 
-   suni_pm7345->suni_rxcp_cell_pat_h1 =
-   	suni_pm7345->suni_rxcp_cell_pat_h2 =
-   	suni_pm7345->suni_rxcp_cell_pat_h3 = 0;
-   suni_pm7345->suni_rxcp_cell_pat_h4 = 1;
- 
-   suni_pm7345->suni_rxcp_cell_mask_h1 =
-   	suni_pm7345->suni_rxcp_cell_mask_h2 =
-   	suni_pm7345->suni_rxcp_cell_mask_h3 =
-   	suni_pm7345->suni_rxcp_cell_mask_h4 = 0xff;
- 
-   suni_pm7345->suni_txcp_ctrl = 0xa4;
-   suni_pm7345->suni_txcp_intr_en_sts = 0x10;
-   suni_pm7345->suni_txcp_idle_pat_h5 = 0x55;
- 
-   suni_pm7345->suni_config &= ~(SUNI_PM7345_LLB |
-                                 SUNI_PM7345_CLB |
-                                 SUNI_PM7345_DLB |
-                                  SUNI_PM7345_PLB);
+	while (len--) {
+		ia_phy_write32(iadev, regs->reg, regs->val);
+		regs++;
+	}
+}
+
+static void ia_suni_pm7345_init_ds3(struct iadev_priv *iadev)
+{
+	static const struct ia_reg suni_ds3_init [] = {
+		{ SUNI_DS3_FRM_INTR_ENBL,	0x17 },
+		{ SUNI_DS3_FRM_CFG,		0x01 },
+		{ SUNI_DS3_TRAN_CFG,		0x01 },
+		{ SUNI_CONFIG,			0 },
+		{ SUNI_SPLR_CFG,		0 },
+		{ SUNI_SPLT_CFG,		0 }
+	};
+	u32 status;
+
+	status = ia_phy_read32(iadev, SUNI_DS3_FRM_STAT);
+	iadev->carrier_detect = (status & SUNI_DS3_LOSV) ? 0 : 1;
+
+	ia_phy_write(iadev, suni_ds3_init, ARRAY_SIZE(suni_ds3_init));
+}
+
+static void ia_suni_pm7345_init_e3(struct iadev_priv *iadev)
+{
+	static const struct ia_reg suni_e3_init [] = {
+		{ SUNI_E3_FRM_FRAM_OPTIONS,		0x04 },
+		{ SUNI_E3_FRM_MAINT_OPTIONS,		0x20 },
+		{ SUNI_E3_FRM_FRAM_INTR_ENBL,		0x1d },
+		{ SUNI_E3_FRM_MAINT_INTR_ENBL,		0x30 },
+		{ SUNI_E3_TRAN_STAT_DIAG_OPTIONS,	0 },
+		{ SUNI_E3_TRAN_FRAM_OPTIONS,		0x01 },
+		{ SUNI_CONFIG,				SUNI_PM7345_E3ENBL },
+		{ SUNI_SPLR_CFG,			0x41 },
+		{ SUNI_SPLT_CFG,			0x41 }
+	};
+	u32 status;
+
+	status = ia_phy_read32(iadev, SUNI_E3_FRM_FRAM_INTR_IND_STAT);
+	iadev->carrier_detect = (status & SUNI_E3_LOS) ? 0 : 1;
+	ia_phy_write(iadev, suni_e3_init, ARRAY_SIZE(suni_e3_init));
+}
+
+static void ia_suni_pm7345_init(struct iadev_priv *iadev)
+{
+	static const struct ia_reg suni_init [] = {
+		/* Enable RSOP loss of signal interrupt. */
+		{ SUNI_INTR_ENBL,		0x28 },
+		/* Clear error counters. */
+		{ SUNI_ID_RESET,		0 },
+		/* Clear "PMCTST" in master test register. */
+		{ SUNI_MASTER_TEST,		0 },
+
+		{ SUNI_RXCP_CTRL,		0x2c },
+		{ SUNI_RXCP_FCTRL,		0x81 },
+
+		{ SUNI_RXCP_IDLE_PAT_H1,	0 },
+		{ SUNI_RXCP_IDLE_PAT_H2,	0 },
+		{ SUNI_RXCP_IDLE_PAT_H3,	0 },
+		{ SUNI_RXCP_IDLE_PAT_H4,	0x01 },
+
+		{ SUNI_RXCP_IDLE_MASK_H1,	0xff },
+		{ SUNI_RXCP_IDLE_MASK_H2,	0xff },
+		{ SUNI_RXCP_IDLE_MASK_H3,	0xff },
+		{ SUNI_RXCP_IDLE_MASK_H4,	0xfe },
+
+		{ SUNI_RXCP_CELL_PAT_H1,	0 },
+		{ SUNI_RXCP_CELL_PAT_H2,	0 },
+		{ SUNI_RXCP_CELL_PAT_H3,	0 },
+		{ SUNI_RXCP_CELL_PAT_H4,	0x01 },
+
+		{ SUNI_RXCP_CELL_MASK_H1,	0xff },
+		{ SUNI_RXCP_CELL_MASK_H2,	0xff },
+		{ SUNI_RXCP_CELL_MASK_H3,	0xff },
+		{ SUNI_RXCP_CELL_MASK_H4,	0xff },
+
+		{ SUNI_TXCP_CTRL,		0xa4 },
+		{ SUNI_TXCP_INTR_EN_STS,	0x10 },
+		{ SUNI_TXCP_IDLE_PAT_H5,	0x55 }
+	};
+
+	if (iadev->phy_type & FE_DS3_PHY)
+		ia_suni_pm7345_init_ds3(iadev);
+	else
+		ia_suni_pm7345_init_e3(iadev);
+
+	ia_phy_write(iadev, suni_init, ARRAY_SIZE(suni_init));
+
+	ia_phy_write32(iadev, SUNI_CONFIG, ia_phy_read32(iadev, SUNI_CONFIG) &
+		~(SUNI_PM7345_LLB | SUNI_PM7345_CLB |
+		  SUNI_PM7345_DLB | SUNI_PM7345_PLB));
 #ifdef __SNMP__
    suni_pm7345->suni_rxcp_intr_en_sts |= SUNI_OOCDE;
 #endif /* __SNMP__ */
@@ -1425,10 +1450,10 @@ static int rx_init(struct atm_dev *dev)
 	       iadev->dma + IPHASE5575_RX_LIST_ADDR);  
 	IF_INIT(printk("Tx Dle list addr: 0x%p value: 0x%0x\n",
                       iadev->dma+IPHASE5575_TX_LIST_ADDR,
-                      *(u32*)(iadev->dma+IPHASE5575_TX_LIST_ADDR));  
+                      readl(iadev->dma + IPHASE5575_TX_LIST_ADDR));
 	printk("Rx Dle list addr: 0x%p value: 0x%0x\n",
                       iadev->dma+IPHASE5575_RX_LIST_ADDR,
-                      *(u32*)(iadev->dma+IPHASE5575_RX_LIST_ADDR));)  
+                      readl(iadev->dma + IPHASE5575_RX_LIST_ADDR));)
   
 	writew(0xffff, iadev->reass_reg+REASS_MASK_REG);  
 	writew(0, iadev->reass_reg+MODE_REG);  
@@ -2208,7 +2233,7 @@ static irqreturn_t ia_int(int irq, void *dev_id)
 	if (status & STAT_DLERINT)  
 	{  
 	   /* Clear this bit by writing a 1 to it. */  
-	   *(u_int *)(iadev->reg+IPHASE5575_BUS_STATUS_REG) = STAT_DLERINT;
+	   writel(STAT_DLERINT, iadev->reg + IPHASE5575_BUS_STATUS_REG);
 	   rx_dle_intr(dev);  
 	}  
 	if (status & STAT_SEGINT)  
@@ -2219,13 +2244,13 @@ static irqreturn_t ia_int(int irq, void *dev_id)
 	}  
 	if (status & STAT_DLETINT)  
 	{  
-	   *(u_int *)(iadev->reg+IPHASE5575_BUS_STATUS_REG) = STAT_DLETINT;  
+	   writel(STAT_DLETINT, iadev->reg + IPHASE5575_BUS_STATUS_REG);
 	   tx_dle_intr(dev);  
 	}  
 	if (status & (STAT_FEINT | STAT_ERRINT | STAT_MARKINT))  
 	{  
            if (status & STAT_FEINT) 
-               IaFrontEndIntr(iadev);
+               ia_frontend_intr(iadev);
 	}  
    }
    return IRQ_RETVAL(handled);
@@ -2556,7 +2581,7 @@ static int __devinit ia_start(struct atm_dev *dev)
 				goto err_free_rx;
 		}
 		/* Get iadev->carrier_detect status */
-		IaFrontEndIntr(iadev);
+		ia_frontend_intr(iadev);
 	}
 	return 0;
 
@@ -2827,7 +2852,7 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
 
          case 0xb:
 	    if (!capable(CAP_NET_ADMIN)) return -EPERM;
-            IaFrontEndIntr(iadev);
+            ia_frontend_intr(iadev);
             break;
          case 0xa:
 	    if (!capable(CAP_NET_ADMIN)) return -EPERM;
diff --git a/drivers/atm/iphase.h b/drivers/atm/iphase.h
index 077735e..6a0955e 100644
--- a/drivers/atm/iphase.h
+++ b/drivers/atm/iphase.h
@@ -889,79 +889,71 @@ typedef struct ia_rtn_q {
 } IARTN_Q;
 
 #define SUNI_LOSV   	0x04
-typedef struct {
-        u32   suni_master_reset;      /* SUNI Master Reset and Identity     */
-        u32   suni_master_config;     /* SUNI Master Configuration          */
-        u32   suni_master_intr_stat;  /* SUNI Master Interrupt Status       */
-        u32   suni_reserved1;         /* Reserved                           */
-        u32   suni_master_clk_monitor;/* SUNI Master Clock Monitor          */
-        u32   suni_master_control;    /* SUNI Master Clock Monitor          */
-        u32   suni_reserved2[10];     /* Reserved                           */
-
-        u32   suni_rsop_control;      /* RSOP Control/Interrupt Enable      */
-        u32   suni_rsop_status;       /* RSOP Status/Interrupt States       */
-        u32   suni_rsop_section_bip8l;/* RSOP Section BIP-8 LSB             */
-        u32   suni_rsop_section_bip8m;/* RSOP Section BIP-8 MSB             */
-
-        u32   suni_tsop_control;      /* TSOP Control                       */
-        u32   suni_tsop_diag;         /* TSOP Disgnostics                   */
-        u32   suni_tsop_reserved[2];  /* TSOP Reserved                      */
-
-        u32   suni_rlop_cs;           /* RLOP Control/Status                */
-        u32   suni_rlop_intr;         /* RLOP Interrupt Enable/Status       */
-        u32   suni_rlop_line_bip24l;  /* RLOP Line BIP-24 LSB               */
-        u32   suni_rlop_line_bip24;   /* RLOP Line BIP-24                   */
-        u32   suni_rlop_line_bip24m;  /* RLOP Line BIP-24 MSB               */
-        u32   suni_rlop_line_febel;   /* RLOP Line FEBE LSB                 */
-        u32   suni_rlop_line_febe;    /* RLOP Line FEBE                     */
-        u32   suni_rlop_line_febem;   /* RLOP Line FEBE MSB                 */
-
-        u32   suni_tlop_control;      /* TLOP Control                       */
-        u32   suni_tlop_disg;         /* TLOP Disgnostics                   */
-        u32   suni_tlop_reserved[14]; /* TLOP Reserved                      */
-
-        u32   suni_rpop_cs;           /* RPOP Status/Control                */
-        u32   suni_rpop_intr;         /* RPOP Interrupt/Status              */
-        u32   suni_rpop_reserved;     /* RPOP Reserved                      */
-        u32   suni_rpop_intr_ena;     /* RPOP Interrupt Enable              */
-        u32   suni_rpop_reserved1[3]; /* RPOP Reserved                      */
-        u32   suni_rpop_path_sig;     /* RPOP Path Signal Label             */
-        u32   suni_rpop_bip8l;        /* RPOP Path BIP-8 LSB                */
-        u32   suni_rpop_bip8m;        /* RPOP Path BIP-8 MSB                */
-        u32   suni_rpop_febel;        /* RPOP Path FEBE LSB                 */
-        u32   suni_rpop_febem;        /* RPOP Path FEBE MSB                 */
-        u32   suni_rpop_reserved2[4]; /* RPOP Reserved                      */
-
-        u32   suni_tpop_cntrl_daig;   /* TPOP Control/Disgnostics           */
-        u32   suni_tpop_pointer_ctrl; /* TPOP Pointer Control               */
-        u32   suni_tpop_sourcer_ctrl; /* TPOP Source Control                */
-        u32   suni_tpop_reserved1[2]; /* TPOP Reserved                      */
-        u32   suni_tpop_arb_prtl;     /* TPOP Arbitrary Pointer LSB         */
-        u32   suni_tpop_arb_prtm;     /* TPOP Arbitrary Pointer MSB         */
-        u32   suni_tpop_reserved2;    /* TPOP Reserved                      */
-        u32   suni_tpop_path_sig;     /* TPOP Path Signal Lable             */
-        u32   suni_tpop_path_status;  /* TPOP Path Status                   */
-        u32   suni_tpop_reserved3[6]; /* TPOP Reserved                      */              
-
-        u32   suni_racp_cs;           /* RACP Control/Status                */
-        u32   suni_racp_intr;         /* RACP Interrupt Enable/Status       */
-        u32   suni_racp_hdr_pattern;  /* RACP Match Header Pattern          */
-        u32   suni_racp_hdr_mask;     /* RACP Match Header Mask             */
-        u32   suni_racp_corr_hcs;     /* RACP Correctable HCS Error Count   */
-        u32   suni_racp_uncorr_hcs;   /* RACP Uncorrectable HCS Error Count */
-        u32   suni_racp_reserved[10]; /* RACP Reserved                      */
-
-        u32   suni_tacp_control;      /* TACP Control                       */
-        u32   suni_tacp_idle_hdr_pat; /* TACP Idle Cell Header Pattern      */
-        u32   suni_tacp_idle_pay_pay; /* TACP Idle Cell Payld Octet Pattern */
-        u32   suni_tacp_reserved[5];  /* TACP Reserved                      */
-
-        u32   suni_reserved3[24];     /* Reserved                           */
-
-        u32   suni_master_test;       /* SUNI Master Test                   */
-        u32   suni_reserved_test;     /* SUNI Reserved for Test             */
-} IA_SUNI;
-
+enum ia_suni {
+	SUNI_MASTER_RESET	= 0x000, /* SUNI Master Reset and Identity   */
+	SUNI_MASTER_CONFIG	= 0x004, /* SUNI Master Configuration        */
+	SUNI_MASTER_INTR_STAT	= 0x008, /* SUNI Master Interrupt Status     */
+	SUNI_RESERVED1		= 0x00c, /* Reserved                         */
+	SUNI_MASTER_CLK_MONITOR	= 0x010, /* SUNI Master Clock Monitor        */
+	SUNI_MASTER_CONTROL	= 0x014, /* SUNI Master Clock Monitor        */
+					 /* Reserved (10)                    */
+	SUNI_RSOP_CONTROL	= 0x040, /* RSOP Control/Interrupt Enable    */
+	SUNI_RSOP_STATUS	= 0x044, /* RSOP Status/Interrupt States     */
+	SUNI_RSOP_SECTION_BIP8L	= 0x048, /* RSOP Section BIP-8 LSB           */
+	SUNI_RSOP_SECTION_BIP8M	= 0x04c, /* RSOP Section BIP-8 MSB           */
+
+	SUNI_TSOP_CONTROL	= 0x050, /* TSOP Control                     */
+	SUNI_TSOP_DIAG		= 0x054, /* TSOP Disgnostics                 */
+					 /* Reserved (2)                     */
+	SUNI_RLOP_CS		= 0x060, /* RLOP Control/Status              */
+	SUNI_RLOP_INTR		= 0x064, /* RLOP Interrupt Enable/Status     */
+	SUNI_RLOP_LINE_BIP24L	= 0x068, /* RLOP Line BIP-24 LSB             */
+	SUNI_RLOP_LINE_BIP24	= 0x06c, /* RLOP Line BIP-24                 */
+	SUNI_RLOP_LINE_BIP24M	= 0x070, /* RLOP Line BIP-24 MSB             */
+	SUNI_RLOP_LINE_FEBEL	= 0x074, /* RLOP Line FEBE LSB               */
+	SUNI_RLOP_LINE_FEBE	= 0x078, /* RLOP Line FEBE                   */
+	SUNI_RLOP_LINE_FEBEM	= 0x07c, /* RLOP Line FEBE MSB               */
+
+	SUNI_TLOP_CONTROL	= 0x080, /* TLOP Control                     */
+	SUNI_TLOP_DISG		= 0x084, /* TLOP Disgnostics                 */
+					 /* Reserved (14)                    */
+	SUNI_RPOP_CS		= 0x0c0, /* RPOP Status/Control              */
+	SUNI_RPOP_INTR		= 0x0c4, /* RPOP Interrupt/Status            */
+	SUNI_RPOP_RESERVED	= 0x0c8, /* RPOP Reserved                    */
+	SUNI_RPOP_INTR_ENA	= 0x0cc, /* RPOP Interrupt Enable            */
+					 /* Reserved (3)                     */
+	SUNI_RPOP_PATH_SIG	= 0x0dc, /* RPOP Path Signal Label           */
+	SUNI_RPOP_BIP8L		= 0x0e0, /* RPOP Path BIP-8 LSB              */
+	SUNI_RPOP_BIP8M		= 0x0e4, /* RPOP Path BIP-8 MSB              */
+	SUNI_RPOP_FEBEL		= 0x0e8, /* RPOP Path FEBE LSB               */
+	SUNI_RPOP_FEBEM		= 0x0ec, /* RPOP Path FEBE MSB               */
+					 /* Reserved (4)                     */
+	SUNI_TPOP_CNTRL_DAIG	= 0x100, /* TPOP Control/Disgnostics         */
+	SUNI_TPOP_POINTER_CTRL	= 0x104, /* TPOP Pointer Control             */
+	SUNI_TPOP_SOURCER_CTRL	= 0x108, /* TPOP Source Control              */
+					 /* Reserved (2)                     */
+	SUNI_TPOP_ARB_PRTL	= 0x114, /* TPOP Arbitrary Pointer LSB       */
+	SUNI_TPOP_ARB_PRTM	= 0x118, /* TPOP Arbitrary Pointer MSB       */
+	SUNI_TPOP_RESERVED2	= 0x11c, /* TPOP Reserved                    */
+	SUNI_TPOP_PATH_SIG	= 0x120, /* TPOP Path Signal Lable           */
+	SUNI_TPOP_PATH_STATUS	= 0x124, /* TPOP Path Status                 */
+					 /* Reserved (6)                     */
+	SUNI_RACP_CS		= 0x140, /* RACP Control/Status              */
+	SUNI_RACP_INTR		= 0x144, /* RACP Interrupt Enable/Status     */
+	SUNI_RACP_HDR_PATTERN	= 0x148, /* RACP Match Header Pattern        */
+	SUNI_RACP_HDR_MASK	= 0x14c, /* RACP Match Header Mask           */
+	SUNI_RACP_CORR_HCS	= 0x150, /* RACP Correctable HCS Error Count */
+	SUNI_RACP_UNCORR_HCS	= 0x154, /* RACP Uncorrectable HCS Err Count */
+					 /* Reserved (10)                    */
+	SUNI_TACP_CONTROL	= 0x180, /* TACP Control                     */
+	SUNI_TACP_IDLE_HDR_PAT	= 0x184, /* TACP Idle Cell Header Pattern    */
+	SUNI_TACP_IDLE_PAY_PAY	= 0x188, /* TACP Idle Cell Payld Octet Patrn */
+					 /* Reserved (5)                     */
+					 /* Reserved (24)                    */
+	/* FIXME: unused but name conflicts.
+	 * SUNI_MASTER_TEST	= 0x200,    SUNI Master Test                 */
+	SUNI_RESERVED_TEST	= 0x204  /* SUNI Reserved for Test           */
+};
 
 typedef struct _SUNI_STATS_
 {
@@ -993,13 +985,11 @@ typedef struct _SUNI_STATS_
    u32 racp_uchcs_count;            // uncorrectable HCS error count
 } IA_SUNI_STATS; 
 
-typedef struct iadev_t {  
+typedef struct iadev_priv {
 	/*-----base pointers into (i)chipSAR+ address space */   
-	u32 __iomem *phy;		/* base pointer into phy(SUNI) */  
-	u32 __iomem *dma;		/* base pointer into DMA control   
-						registers */  
-	u32 __iomem *reg;		/* base pointer to SAR registers  
-					   - Bus Interface Control Regs */  
+	u32 __iomem *phy;	/* Base pointer into phy (SUNI). */
+	u32 __iomem *dma;	/* Base pointer into DMA control registers. */
+	u32 __iomem *reg;	/* Base pointer to SAR registers. */
 	u32 __iomem *seg_reg;		/* base pointer to segmentation engine  
 						internal registers */  
 	u32 __iomem *reass_reg;		/* base pointer to reassemble engine  
@@ -1071,14 +1061,14 @@ typedef struct iadev_t {
 #define INPH_IA_VCC(v) ((struct ia_vcc *) (v)->dev_data)  
 
 /******************* IDT77105 25MB/s PHY DEFINE *****************************/
-typedef struct {
-	u_int	mb25_master_ctrl;	/* Master control		     */
-	u_int	mb25_intr_status;	/* Interrupt status		     */
-	u_int	mb25_diag_control;	/* Diagnostic control		     */
-	u_int	mb25_led_hec;		/* LED driver and HEC status/control */
-	u_int	mb25_low_byte_counter;	/* Low byte counter		     */
-	u_int	mb25_high_byte_counter;	/* High byte counter		     */
-} ia_mb25_t;
+enum ia_mb25 {
+	MB25_MASTER_CTRL	= 0x00, /* Master control		     */
+	MB25_INTR_STATUS	= 0x04,	/* Interrupt status		     */
+	MB25_DIAG_CONTROL	= 0x08,	/* Diagnostic control		     */
+	MB25_LED_HEC		= 0x0c,	/* LED driver and HEC status/control */
+	MB25_LOW_BYTE_COUNTER	= 0x10,
+	MB25_HIGH_BYTE_COUNTER	= 0x14
+};
 
 /*
  * Master Control
@@ -1127,122 +1117,121 @@ typedef struct {
 #define FE_E3_PHY       0x0090          /* E3 */
 		     
 /*********************** SUNI_PM7345 PHY DEFINE HERE *********************/
-typedef struct _suni_pm7345_t
-{
-    u_int suni_config;     /* SUNI Configuration */
-    u_int suni_intr_enbl;  /* SUNI Interrupt Enable */
-    u_int suni_intr_stat;  /* SUNI Interrupt Status */
-    u_int suni_control;    /* SUNI Control */
-    u_int suni_id_reset;   /* SUNI Reset and Identity */
-    u_int suni_data_link_ctrl;
-    u_int suni_rboc_conf_intr_enbl;
-    u_int suni_rboc_stat;
-    u_int suni_ds3_frm_cfg;
-    u_int suni_ds3_frm_intr_enbl;
-    u_int suni_ds3_frm_intr_stat;
-    u_int suni_ds3_frm_stat;
-    u_int suni_rfdl_cfg;
-    u_int suni_rfdl_enbl_stat;
-    u_int suni_rfdl_stat;
-    u_int suni_rfdl_data;
-    u_int suni_pmon_chng;
-    u_int suni_pmon_intr_enbl_stat;
-    u_int suni_reserved1[0x13-0x11];
-    u_int suni_pmon_lcv_evt_cnt_lsb;
-    u_int suni_pmon_lcv_evt_cnt_msb;
-    u_int suni_pmon_fbe_evt_cnt_lsb;
-    u_int suni_pmon_fbe_evt_cnt_msb;
-    u_int suni_pmon_sez_det_cnt_lsb;
-    u_int suni_pmon_sez_det_cnt_msb;
-    u_int suni_pmon_pe_evt_cnt_lsb;
-    u_int suni_pmon_pe_evt_cnt_msb;
-    u_int suni_pmon_ppe_evt_cnt_lsb;
-    u_int suni_pmon_ppe_evt_cnt_msb;
-    u_int suni_pmon_febe_evt_cnt_lsb;
-    u_int suni_pmon_febe_evt_cnt_msb;
-    u_int suni_ds3_tran_cfg;
-    u_int suni_ds3_tran_diag;
-    u_int suni_reserved2[0x23-0x21];
-    u_int suni_xfdl_cfg;
-    u_int suni_xfdl_intr_st;
-    u_int suni_xfdl_xmit_data;
-    u_int suni_xboc_code;
-    u_int suni_splr_cfg;
-    u_int suni_splr_intr_en;
-    u_int suni_splr_intr_st;
-    u_int suni_splr_status;
-    u_int suni_splt_cfg;
-    u_int suni_splt_cntl;
-    u_int suni_splt_diag_g1;
-    u_int suni_splt_f1;
-    u_int suni_cppm_loc_meters;
-    u_int suni_cppm_chng_of_cppm_perf_meter;
-    u_int suni_cppm_b1_err_cnt_lsb;
-    u_int suni_cppm_b1_err_cnt_msb;
-    u_int suni_cppm_framing_err_cnt_lsb;
-    u_int suni_cppm_framing_err_cnt_msb;
-    u_int suni_cppm_febe_cnt_lsb;
-    u_int suni_cppm_febe_cnt_msb;
-    u_int suni_cppm_hcs_err_cnt_lsb;
-    u_int suni_cppm_hcs_err_cnt_msb;
-    u_int suni_cppm_idle_un_cell_cnt_lsb;
-    u_int suni_cppm_idle_un_cell_cnt_msb;
-    u_int suni_cppm_rcv_cell_cnt_lsb;
-    u_int suni_cppm_rcv_cell_cnt_msb;
-    u_int suni_cppm_xmit_cell_cnt_lsb;
-    u_int suni_cppm_xmit_cell_cnt_msb;
-    u_int suni_rxcp_ctrl;
-    u_int suni_rxcp_fctrl;
-    u_int suni_rxcp_intr_en_sts;
-    u_int suni_rxcp_idle_pat_h1;
-    u_int suni_rxcp_idle_pat_h2;
-    u_int suni_rxcp_idle_pat_h3;
-    u_int suni_rxcp_idle_pat_h4;
-    u_int suni_rxcp_idle_mask_h1;
-    u_int suni_rxcp_idle_mask_h2;
-    u_int suni_rxcp_idle_mask_h3;
-    u_int suni_rxcp_idle_mask_h4;
-    u_int suni_rxcp_cell_pat_h1;
-    u_int suni_rxcp_cell_pat_h2;
-    u_int suni_rxcp_cell_pat_h3;
-    u_int suni_rxcp_cell_pat_h4;
-    u_int suni_rxcp_cell_mask_h1;
-    u_int suni_rxcp_cell_mask_h2;
-    u_int suni_rxcp_cell_mask_h3;
-    u_int suni_rxcp_cell_mask_h4;
-    u_int suni_rxcp_hcs_cs;
-    u_int suni_rxcp_lcd_cnt_threshold;
-    u_int suni_reserved3[0x57-0x54];
-    u_int suni_txcp_ctrl;
-    u_int suni_txcp_intr_en_sts;
-    u_int suni_txcp_idle_pat_h1;
-    u_int suni_txcp_idle_pat_h2;
-    u_int suni_txcp_idle_pat_h3;
-    u_int suni_txcp_idle_pat_h4;
-    u_int suni_txcp_idle_pat_h5;
-    u_int suni_txcp_idle_payload;
-    u_int suni_e3_frm_fram_options;
-    u_int suni_e3_frm_maint_options;
-    u_int suni_e3_frm_fram_intr_enbl;
-    u_int suni_e3_frm_fram_intr_ind_stat;
-    u_int suni_e3_frm_maint_intr_enbl;
-    u_int suni_e3_frm_maint_intr_ind;
-    u_int suni_e3_frm_maint_stat;
-    u_int suni_reserved4;
-    u_int suni_e3_tran_fram_options;
-    u_int suni_e3_tran_stat_diag_options;
-    u_int suni_e3_tran_bip_8_err_mask;
-    u_int suni_e3_tran_maint_adapt_options;
-    u_int suni_ttb_ctrl;
-    u_int suni_ttb_trail_trace_id_stat;
-    u_int suni_ttb_ind_addr;
-    u_int suni_ttb_ind_data;
-    u_int suni_ttb_exp_payload_type;
-    u_int suni_ttb_payload_type_ctrl_stat;
-    u_int suni_pad5[0x7f-0x71];
-    u_int suni_master_test;
-    u_int suni_pad6[0xff-0x80];
-}suni_pm7345_t;
+enum suni_pm7345 {
+	SUNI_CONFIG			= 0x000, /* SUNI Configuration */
+	SUNI_INTR_ENBL			= 0x004, /* SUNI Interrupt Enable */
+	SUNI_INTR_STAT			= 0x008, /* SUNI Interrupt Status */
+	SUNI_CONTROL			= 0x00c, /* SUNI Control */
+	SUNI_ID_RESET			= 0x010, /* SUNI Reset and Identity */
+	SUNI_DATA_LINK_CTRL		= 0x014,
+	SUNI_RBOC_CONF_INTR_ENBL	= 0x018,
+	SUNI_RBOC_STAT			= 0x01c,
+	SUNI_DS3_FRM_CFG		= 0x020,
+	SUNI_DS3_FRM_INTR_ENBL		= 0x024,
+	SUNI_DS3_FRM_INTR_STAT		= 0x028,
+	SUNI_DS3_FRM_STAT		= 0x02c,
+	SUNI_RFDL_CFG			= 0x030,
+	SUNI_RFDL_ENBL_STAT		= 0x034,
+	SUNI_RFDL_STAT			= 0x038,
+	SUNI_RFDL_DATA			= 0x03c,
+	SUNI_PMON_CHNG			= 0x040,
+	SUNI_PMON_INTR_ENBL_STAT	= 0x044,
+	/* SUNI_RESERVED1 (0x13 - 0x11) */
+	SUNI_PMON_LCV_EVT_CNT_LSB	= 0x050,
+	SUNI_PMON_LCV_EVT_CNT_MSB	= 0x054,
+	SUNI_PMON_FBE_EVT_CNT_LSB	= 0x058,
+	SUNI_PMON_FBE_EVT_CNT_MSB	= 0x05c,
+	SUNI_PMON_SEZ_DET_CNT_LSB	= 0x060,
+	SUNI_PMON_SEZ_DET_CNT_MSB	= 0x064,
+	SUNI_PMON_PE_EVT_CNT_LSB	= 0x068,
+	SUNI_PMON_PE_EVT_CNT_MSB	= 0x06c,
+	SUNI_PMON_PPE_EVT_CNT_LSB	= 0x070,
+	SUNI_PMON_PPE_EVT_CNT_MSB	= 0x074,
+	SUNI_PMON_FEBE_EVT_CNT_LSB	= 0x078,
+	SUNI_PMON_FEBE_EVT_CNT_MSB	= 0x07c,
+	SUNI_DS3_TRAN_CFG		= 0x080,
+	SUNI_DS3_TRAN_DIAG		= 0x084,
+	/* SUNI_RESERVED2 (0x23 - 0x21) */
+	SUNI_XFDL_CFG			= 0x090,
+	SUNI_XFDL_INTR_ST		= 0x094,
+	SUNI_XFDL_XMIT_DATA		= 0x098,
+	SUNI_XBOC_CODE			= 0x09c,
+	SUNI_SPLR_CFG			= 0x0a0,
+	SUNI_SPLR_INTR_EN		= 0x0a4,
+	SUNI_SPLR_INTR_ST		= 0x0a8,
+	SUNI_SPLR_STATUS		= 0x0ac,
+	SUNI_SPLT_CFG			= 0x0b0,
+	SUNI_SPLT_CNTL			= 0x0b4,
+	SUNI_SPLT_DIAG_G1		= 0x0b8,
+	SUNI_SPLT_F1			= 0x0bc,
+	SUNI_CPPM_LOC_METERS		= 0x0c0,
+	SUNI_CPPM_CHG_OF_CPPM_PERF_METR	= 0x0c4,
+	SUNI_CPPM_B1_ERR_CNT_LSB	= 0x0c8,
+	SUNI_CPPM_B1_ERR_CNT_MSB	= 0x0cc,
+	SUNI_CPPM_FRAMING_ERR_CNT_LSB	= 0x0d0,
+	SUNI_CPPM_FRAMING_ERR_CNT_MSB	= 0x0d4,
+	SUNI_CPPM_FEBE_CNT_LSB		= 0x0d8,
+	SUNI_CPPM_FEBE_CNT_MSB		= 0x0dc,
+	SUNI_CPPM_HCS_ERR_CNT_LSB	= 0x0e0,
+	SUNI_CPPM_HCS_ERR_CNT_MSB	= 0x0e4,
+	SUNI_CPPM_IDLE_UN_CELL_CNT_LSB	= 0x0e8,
+	SUNI_CPPM_IDLE_UN_CELL_CNT_MSB	= 0x0ec,
+	SUNI_CPPM_RCV_CELL_CNT_LSB	= 0x0f0,
+	SUNI_CPPM_RCV_CELL_CNT_MSB	= 0x0f4,
+	SUNI_CPPM_XMIT_CELL_CNT_LSB	= 0x0f8,
+	SUNI_CPPM_XMIT_CELL_CNT_MSB	= 0x0fc,
+	SUNI_RXCP_CTRL			= 0x100,
+	SUNI_RXCP_FCTRL			= 0x104,
+	SUNI_RXCP_INTR_EN_STS		= 0x108,
+	SUNI_RXCP_IDLE_PAT_H1		= 0x10c,
+	SUNI_RXCP_IDLE_PAT_H2		= 0x110,
+	SUNI_RXCP_IDLE_PAT_H3		= 0x114,
+	SUNI_RXCP_IDLE_PAT_H4		= 0x118,
+	SUNI_RXCP_IDLE_MASK_H1		= 0x11c,
+	SUNI_RXCP_IDLE_MASK_H2		= 0x120,
+	SUNI_RXCP_IDLE_MASK_H3		= 0x124,
+	SUNI_RXCP_IDLE_MASK_H4		= 0x128,
+	SUNI_RXCP_CELL_PAT_H1		= 0x12c,
+	SUNI_RXCP_CELL_PAT_H2		= 0x130,
+	SUNI_RXCP_CELL_PAT_H3		= 0x134,
+	SUNI_RXCP_CELL_PAT_H4		= 0x138,
+	SUNI_RXCP_CELL_MASK_H1		= 0x13c,
+	SUNI_RXCP_CELL_MASK_H2		= 0x140,
+	SUNI_RXCP_CELL_MASK_H3		= 0x144,
+	SUNI_RXCP_CELL_MASK_H4		= 0x148,
+	SUNI_RXCP_HCS_CS		= 0x14c,
+	SUNI_RXCP_LCD_CNT_THRESHOLD	= 0x150,
+	/* SUNI_RESERVED3 (0x57 - 0x54) */
+	SUNI_TXCP_CTRL			= 0x160,
+	SUNI_TXCP_INTR_EN_STS		= 0x164,
+	SUNI_TXCP_IDLE_PAT_H1		= 0x168,
+	SUNI_TXCP_IDLE_PAT_H2		= 0x16c,
+	SUNI_TXCP_IDLE_PAT_H3		= 0x170,
+	SUNI_TXCP_IDLE_PAT_H4		= 0x174,
+	SUNI_TXCP_IDLE_PAT_H5		= 0x178,
+	SUNI_TXCP_IDLE_PAYLOAD		= 0x17c,
+	SUNI_E3_FRM_FRAM_OPTIONS	= 0x180,
+	SUNI_E3_FRM_MAINT_OPTIONS	= 0x184,
+	SUNI_E3_FRM_FRAM_INTR_ENBL	= 0x188,
+	SUNI_E3_FRM_FRAM_INTR_IND_STAT	= 0x18c,
+	SUNI_E3_FRM_MAINT_INTR_ENBL	= 0x190,
+	SUNI_E3_FRM_MAINT_INTR_IND	= 0x194,
+	SUNI_E3_FRM_MAINT_STAT		= 0x198,
+	SUNI_RESERVED4			= 0x19c,
+	SUNI_E3_TRAN_FRAM_OPTIONS	= 0x1a0,
+	SUNI_E3_TRAN_STAT_DIAG_OPTIONS	= 0x1a4,
+	SUNI_E3_TRAN_BIP_8_ERR_MASK	= 0x1a8,
+	SUNI_E3_TRAN_MAINT_ADAPT_OPTS	= 0x1ac,
+	SUNI_TTB_CTRL			= 0x1b0,
+	SUNI_TTB_TRAIL_TRACE_ID_STAT	= 0x1b4,
+	SUNI_TTB_IND_ADDR		= 0x1b8,
+	SUNI_TTB_IND_DATA		= 0x1bc,
+	SUNI_TTB_EXP_PAYLOAD_TYPE	= 0x1c0,
+	SUNI_TTB_PAYLOAD_TYPE_CTRL_STAT	= 0x1c4,
+	/* SUNI_PAD5 (0x7f - 0x71) */
+	SUNI_MASTER_TEST		= 0x200,
+	/* SUNI_PAD6 (0xff - 0x80) */
+};
 
 #define SUNI_PM7345_T suni_pm7345_t
 #define SUNI_PM7345     0x20            /* Suni chip type */
diff --git a/drivers/net/ethernet/amd/depca.h b/drivers/net/ethernet/amd/depca.h
index ee42648..cdcfe42 100644
--- a/drivers/net/ethernet/amd/depca.h
+++ b/drivers/net/ethernet/amd/depca.h
@@ -157,8 +157,6 @@
 */
 #include <linux/sockios.h>
 
-#define	DEPCAIOCTL	SIOCDEVPRIVATE
-
 struct depca_ioctl {
 	unsigned short cmd;                /* Command to run */
 	unsigned short len;                /* Length of the data buffer */
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 9afb653..21bdda3 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -3623,7 +3623,7 @@ bnx2_set_rx_mode(struct net_device *dev)
 	spin_unlock_bh(&bp->phy_lock);
 }
 
-static int __devinit
+static int
 check_fw_section(const struct firmware *fw,
 		 const struct bnx2_fw_file_section *section,
 		 u32 alignment, bool non_empty)
@@ -3639,7 +3639,7 @@ check_fw_section(const struct firmware *fw,
 	return 0;
 }
 
-static int __devinit
+static int
 check_mips_fw_entry(const struct firmware *fw,
 		    const struct bnx2_mips_fw_file_entry *entry)
 {
@@ -3650,8 +3650,16 @@ check_mips_fw_entry(const struct firmware *fw,
 	return 0;
 }
 
-static int __devinit
-bnx2_request_firmware(struct bnx2 *bp)
+static void bnx2_release_firmware(struct bnx2 *bp)
+{
+	if (bp->rv2p_firmware) {
+		release_firmware(bp->mips_firmware);
+		release_firmware(bp->rv2p_firmware);
+		bp->rv2p_firmware = NULL;
+	}
+}
+
+static int bnx2_request_uncached_firmware(struct bnx2 *bp)
 {
 	const char *mips_fw_file, *rv2p_fw_file;
 	const struct bnx2_mips_fw_file *mips_fw;
@@ -3673,13 +3681,13 @@ bnx2_request_firmware(struct bnx2 *bp)
 	rc = request_firmware(&bp->mips_firmware, mips_fw_file, &bp->pdev->dev);
 	if (rc) {
 		pr_err("Can't load firmware file \"%s\"\n", mips_fw_file);
-		return rc;
+		goto out;
 	}
 
 	rc = request_firmware(&bp->rv2p_firmware, rv2p_fw_file, &bp->pdev->dev);
 	if (rc) {
 		pr_err("Can't load firmware file \"%s\"\n", rv2p_fw_file);
-		return rc;
+		goto err_release_mips_firmware;
 	}
 	mips_fw = (const struct bnx2_mips_fw_file *) bp->mips_firmware->data;
 	rv2p_fw = (const struct bnx2_rv2p_fw_file *) bp->rv2p_firmware->data;
@@ -3690,16 +3698,30 @@ bnx2_request_firmware(struct bnx2 *bp)
 	    check_mips_fw_entry(bp->mips_firmware, &mips_fw->tpat) ||
 	    check_mips_fw_entry(bp->mips_firmware, &mips_fw->txp)) {
 		pr_err("Firmware file \"%s\" is invalid\n", mips_fw_file);
-		return -EINVAL;
+		rc = -EINVAL;
+		goto err_release_firmware;
 	}
 	if (bp->rv2p_firmware->size < sizeof(*rv2p_fw) ||
 	    check_fw_section(bp->rv2p_firmware, &rv2p_fw->proc1.rv2p, 8, true) ||
 	    check_fw_section(bp->rv2p_firmware, &rv2p_fw->proc2.rv2p, 8, true)) {
 		pr_err("Firmware file \"%s\" is invalid\n", rv2p_fw_file);
-		return -EINVAL;
+		rc = -EINVAL;
+		goto err_release_firmware;
 	}
+out:
+	return rc;
 
-	return 0;
+err_release_firmware:
+	release_firmware(bp->rv2p_firmware);
+	bp->rv2p_firmware = NULL;
+err_release_mips_firmware:
+	release_firmware(bp->mips_firmware);
+	goto out;
+}
+
+static int bnx2_request_firmware(struct bnx2 *bp)
+{
+	return bp->rv2p_firmware ? 0 : bnx2_request_uncached_firmware(bp);
 }
 
 static u32
@@ -6267,6 +6289,10 @@ bnx2_open(struct net_device *dev)
 	struct bnx2 *bp = netdev_priv(dev);
 	int rc;
 
+	rc = bnx2_request_firmware(bp);
+	if (rc < 0)
+		goto out;
+
 	netif_carrier_off(dev);
 
 	bnx2_set_power_state(bp, PCI_D0);
@@ -6327,8 +6353,8 @@ bnx2_open(struct net_device *dev)
 		netdev_info(dev, "using MSIX\n");
 
 	netif_tx_start_all_queues(dev);
-
-	return 0;
+out:
+	return rc;
 
 open_err:
 	bnx2_napi_disable(bp);
@@ -6336,7 +6362,8 @@ open_err:
 	bnx2_free_irq(bp);
 	bnx2_free_mem(bp);
 	bnx2_del_napi(bp);
-	return rc;
+	bnx2_release_firmware(bp);
+	goto out;
 }
 
 static void
@@ -8354,10 +8381,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	pci_set_drvdata(pdev, dev);
 
-	rc = bnx2_request_firmware(bp);
-	if (rc)
-		goto error;
-
 	memcpy(dev->dev_addr, bp->mac_addr, 6);
 	memcpy(dev->perm_addr, bp->mac_addr, 6);
 
@@ -8389,11 +8412,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	return 0;
 
 error:
-	if (bp->mips_firmware)
-		release_firmware(bp->mips_firmware);
-	if (bp->rv2p_firmware)
-		release_firmware(bp->rv2p_firmware);
-
 	if (bp->regview)
 		iounmap(bp->regview);
 	pci_release_regions(pdev);
@@ -8414,11 +8432,6 @@ bnx2_remove_one(struct pci_dev *pdev)
 	del_timer_sync(&bp->timer);
 	cancel_work_sync(&bp->reset_task);
 
-	if (bp->mips_firmware)
-		release_firmware(bp->mips_firmware);
-	if (bp->rv2p_firmware)
-		release_firmware(bp->rv2p_firmware);
-
 	if (bp->regview)
 		iounmap(bp->regview);
 
@@ -8429,6 +8442,8 @@ bnx2_remove_one(struct pci_dev *pdev)
 		bp->flags &= ~BNX2_FLAG_AER_ENABLED;
 	}
 
+	bnx2_release_firmware(bp);
+
 	free_netdev(dev);
 
 	pci_release_regions(pdev);
diff --git a/drivers/net/ethernet/dec/tulip/de4x5.h b/drivers/net/ethernet/dec/tulip/de4x5.h
index 9f28774..ec756eb 100644
--- a/drivers/net/ethernet/dec/tulip/de4x5.h
+++ b/drivers/net/ethernet/dec/tulip/de4x5.h
@@ -991,8 +991,6 @@
 */
 #include <linux/sockios.h>
 
-#define	DE4X5IOCTL	SIOCDEVPRIVATE
-
 struct de4x5_ioctl {
 	unsigned short cmd;                /* Command to run */
 	unsigned short len;                /* Length of the data buffer */
diff --git a/drivers/net/ethernet/jme.h b/drivers/net/ethernet/jme.h
index c1f8b89..02ea27c 100644
--- a/drivers/net/ethernet/jme.h
+++ b/drivers/net/ethernet/jme.h
@@ -102,7 +102,6 @@ enum jme_spi_op_bits {
 };
 
 #define HALF_US 500	/* 500 ns */
-#define JMESPIIOCTL	SIOCDEVPRIVATE
 
 #define PCI_PRIV_PE1		0xE4
 
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
index c77d5af..60c8de5 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -55,8 +55,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/compiler.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/init.h>
@@ -65,7 +63,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/ethtool.h>
-#include <linux/gfp.h>
 #include <linux/mii.h>
 #include <linux/if_vlan.h>
 #include <linux/crc32.h>
@@ -73,10 +70,8 @@
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
-#include <linux/cache.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/uaccess.h>
 
 /* These identify the driver base version and may not be removed. */
 static char version[] =
diff --git a/drivers/net/ethernet/realtek/sc92031.c b/drivers/net/ethernet/realtek/sc92031.c
index 128f8eb..a284d64 100644
--- a/drivers/net/ethernet/realtek/sc92031.c
+++ b/drivers/net/ethernet/realtek/sc92031.c
@@ -31,6 +31,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
+#include <linux/mii.h>
 #include <linux/crc32.h>
 
 #include <asm/irq.h>
@@ -116,16 +117,9 @@ enum  silan_registers {
    TestD8     = 0xD8,
 };
 
-#define MII_BMCR            0        // Basic mode control register
-#define MII_BMSR            1        // Basic mode status register
 #define MII_JAB             16
 #define MII_OutputStatus    24
 
-#define BMCR_FULLDPLX       0x0100    // Full duplex
-#define BMCR_ANRESTART      0x0200    // Auto negotiation restart
-#define BMCR_ANENABLE       0x1000    // Enable auto negotiation
-#define BMCR_SPEED100       0x2000    // Select 100Mbps
-#define BMSR_LSTATUS        0x0004    // Link status
 #define PHY_16_JAB_ENB      0x1000
 #define PHY_16_PORT_ENB     0x1
 
diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c
index 371ab7a..1151cf9 100644
--- a/drivers/net/ethernet/tehuti/tehuti.c
+++ b/drivers/net/ethernet/tehuti/tehuti.c
@@ -67,10 +67,10 @@
 #include "tehuti.h"
 
 static DEFINE_PCI_DEVICE_TABLE(bdx_pci_tbl) = {
-	{0x1FC9, 0x3009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x1FC9, 0x3010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x1FC9, 0x3014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0}
+	{ PCI_VDEVICE(TEHUTI, 0x3009), },
+	{ PCI_VDEVICE(TEHUTI, 0x3010), },
+	{ PCI_VDEVICE(TEHUTI, 0x3014), },
+	{ 0 }
 };
 
 MODULE_DEVICE_TABLE(pci, bdx_pci_tbl);
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
index b00d692..bf8c84d 100644
--- a/drivers/net/usb/rtl8150.c
+++ b/drivers/net/usb/rtl8150.c
@@ -169,26 +169,8 @@ struct rtl8150 {
 
 typedef struct rtl8150 rtl8150_t;
 
-static void fill_skb_pool(rtl8150_t *);
-static void free_skb_pool(rtl8150_t *);
-static inline struct sk_buff *pull_skb(rtl8150_t *);
-static void rtl8150_disconnect(struct usb_interface *intf);
-static int rtl8150_probe(struct usb_interface *intf,
-			   const struct usb_device_id *id);
-static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message);
-static int rtl8150_resume(struct usb_interface *intf);
-
 static const char driver_name [] = "rtl8150";
 
-static struct usb_driver rtl8150_driver = {
-	.name =		driver_name,
-	.probe =	rtl8150_probe,
-	.disconnect =	rtl8150_disconnect,
-	.id_table =	rtl8150_table,
-	.suspend =	rtl8150_suspend,
-	.resume =	rtl8150_resume
-};
-
 /*
 **
 **	device related part of the code
@@ -333,7 +315,7 @@ static int rtl8150_set_mac_address(struct net_device *netdev, void *p)
 	/* Write the MAC address into eeprom. Eeprom writes must be word-sized,
 	   so we need to split them up. */
 	for (i = 0; i * 2 < netdev->addr_len; i++) {
-		set_registers(dev, IDR_EEPROM + (i * 2), 2, 
+		set_registers(dev, IDR_EEPROM + (i * 2), 2,
 		netdev->dev_addr + (i * 2));
 	}
 	/* Clear the WEPROM bit (preventing accidental eeprom writes). */
@@ -490,44 +472,6 @@ resched:
 	tasklet_schedule(&dev->tl);
 }
 
-static void rx_fixup(unsigned long data)
-{
-	rtl8150_t *dev;
-	struct sk_buff *skb;
-	int status;
-
-	dev = (rtl8150_t *)data;
-
-	spin_lock_irq(&dev->rx_pool_lock);
-	fill_skb_pool(dev);
-	spin_unlock_irq(&dev->rx_pool_lock);
-	if (test_bit(RX_URB_FAIL, &dev->flags))
-		if (dev->rx_skb)
-			goto try_again;
-	spin_lock_irq(&dev->rx_pool_lock);
-	skb = pull_skb(dev);
-	spin_unlock_irq(&dev->rx_pool_lock);
-	if (skb == NULL)
-		goto tlsched;
-	dev->rx_skb = skb;
-	usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
-		      dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
-try_again:
-	status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
-	if (status == -ENODEV) {
-		netif_device_detach(dev->netdev);
-	} else if (status) {
-		set_bit(RX_URB_FAIL, &dev->flags);
-		goto tlsched;
-	} else {
-		clear_bit(RX_URB_FAIL, &dev->flags);
-	}
-
-	return;
-tlsched:
-	tasklet_schedule(&dev->tl);
-}
-
 static void write_bulk_callback(struct urb *urb)
 {
 	rtl8150_t *dev;
@@ -665,6 +609,42 @@ static void free_skb_pool(rtl8150_t *dev)
 			dev_kfree_skb(dev->rx_skb_pool[i]);
 }
 
+static void rx_fixup(unsigned long data)
+{
+	struct rtl8150 *dev = (struct rtl8150 *)data;
+	struct sk_buff *skb;
+	int status;
+
+	spin_lock_irq(&dev->rx_pool_lock);
+	fill_skb_pool(dev);
+	spin_unlock_irq(&dev->rx_pool_lock);
+	if (test_bit(RX_URB_FAIL, &dev->flags))
+		if (dev->rx_skb)
+			goto try_again;
+	spin_lock_irq(&dev->rx_pool_lock);
+	skb = pull_skb(dev);
+	spin_unlock_irq(&dev->rx_pool_lock);
+	if (skb == NULL)
+		goto tlsched;
+	dev->rx_skb = skb;
+	usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
+		      dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
+try_again:
+	status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
+	if (status == -ENODEV) {
+		netif_device_detach(dev->netdev);
+	} else if (status) {
+		set_bit(RX_URB_FAIL, &dev->flags);
+		goto tlsched;
+	} else {
+		clear_bit(RX_URB_FAIL, &dev->flags);
+	}
+
+	return;
+tlsched:
+	tasklet_schedule(&dev->tl);
+}
+
 static int enable_net_traffic(rtl8150_t * dev)
 {
 	u8 cr, tcr, rcr, msr;
@@ -778,7 +758,7 @@ static int rtl8150_open(struct net_device *netdev)
 		return -ENOMEM;
 
 	set_registers(dev, IDR, 6, netdev->dev_addr);
-	
+
 	usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
 		      dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
 	if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) {
@@ -898,7 +878,7 @@ static const struct net_device_ops rtl8150_netdev_ops = {
 	.ndo_stop		= rtl8150_close,
 	.ndo_do_ioctl		= rtl8150_ioctl,
 	.ndo_start_xmit		= rtl8150_start_xmit,
-	.ndo_tx_timeout 	= rtl8150_tx_timeout,
+	.ndo_tx_timeout		= rtl8150_tx_timeout,
 	.ndo_set_rx_mode	= rtl8150_set_multicast,
 	.ndo_set_mac_address	= rtl8150_set_mac_address,
 
@@ -929,7 +909,7 @@ static int rtl8150_probe(struct usb_interface *intf,
 
 	tasklet_init(&dev->tl, rx_fixup, (unsigned long)dev);
 	spin_lock_init(&dev->rx_pool_lock);
-	
+
 	dev->udev = udev;
 	dev->netdev = netdev;
 	netdev->netdev_ops = &rtl8150_netdev_ops;
@@ -947,7 +927,7 @@ static int rtl8150_probe(struct usb_interface *intf,
 	}
 	fill_skb_pool(dev);
 	set_ethernet_addr(dev);
-	
+
 	usb_set_intfdata(intf, dev);
 	SET_NETDEV_DEV(netdev, &intf->dev);
 	if (register_netdev(netdev) != 0) {
@@ -989,6 +969,15 @@ static void rtl8150_disconnect(struct usb_interface *intf)
 	}
 }
 
+static struct usb_driver rtl8150_driver = {
+	.name		= driver_name,
+	.probe		= rtl8150_probe,
+	.disconnect	= rtl8150_disconnect,
+	.id_table	= rtl8150_table,
+	.suspend	= rtl8150_suspend,
+	.resume		= rtl8150_resume
+};
+
 static int __init usb_rtl8150_init(void)
 {
 	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
-- 
Ueimor

^ permalink raw reply related

* [PATCH next 1/7] bnx2: don't request firmware when there's no userspace.
From: Francois Romieu @ 2011-09-30 10:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, Michael Chan
In-Reply-To: <20110930103604.GA26727@electric-eye.fr.zoreil.com>

The firmware is cached during the first successful call to open() and
released once the network device is unregistered. The driver uses the
cached firmware between open() and unregister_netdev().

It's similar to 953a12cc2889d1be92e80a2d0bab5ffef4942300 but the
firmware is mandatory.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2.c |   67 +++++++++++++++++++++-------------
 1 files changed, 41 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 9afb653..21bdda3 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -3623,7 +3623,7 @@ bnx2_set_rx_mode(struct net_device *dev)
 	spin_unlock_bh(&bp->phy_lock);
 }
 
-static int __devinit
+static int
 check_fw_section(const struct firmware *fw,
 		 const struct bnx2_fw_file_section *section,
 		 u32 alignment, bool non_empty)
@@ -3639,7 +3639,7 @@ check_fw_section(const struct firmware *fw,
 	return 0;
 }
 
-static int __devinit
+static int
 check_mips_fw_entry(const struct firmware *fw,
 		    const struct bnx2_mips_fw_file_entry *entry)
 {
@@ -3650,8 +3650,16 @@ check_mips_fw_entry(const struct firmware *fw,
 	return 0;
 }
 
-static int __devinit
-bnx2_request_firmware(struct bnx2 *bp)
+static void bnx2_release_firmware(struct bnx2 *bp)
+{
+	if (bp->rv2p_firmware) {
+		release_firmware(bp->mips_firmware);
+		release_firmware(bp->rv2p_firmware);
+		bp->rv2p_firmware = NULL;
+	}
+}
+
+static int bnx2_request_uncached_firmware(struct bnx2 *bp)
 {
 	const char *mips_fw_file, *rv2p_fw_file;
 	const struct bnx2_mips_fw_file *mips_fw;
@@ -3673,13 +3681,13 @@ bnx2_request_firmware(struct bnx2 *bp)
 	rc = request_firmware(&bp->mips_firmware, mips_fw_file, &bp->pdev->dev);
 	if (rc) {
 		pr_err("Can't load firmware file \"%s\"\n", mips_fw_file);
-		return rc;
+		goto out;
 	}
 
 	rc = request_firmware(&bp->rv2p_firmware, rv2p_fw_file, &bp->pdev->dev);
 	if (rc) {
 		pr_err("Can't load firmware file \"%s\"\n", rv2p_fw_file);
-		return rc;
+		goto err_release_mips_firmware;
 	}
 	mips_fw = (const struct bnx2_mips_fw_file *) bp->mips_firmware->data;
 	rv2p_fw = (const struct bnx2_rv2p_fw_file *) bp->rv2p_firmware->data;
@@ -3690,16 +3698,30 @@ bnx2_request_firmware(struct bnx2 *bp)
 	    check_mips_fw_entry(bp->mips_firmware, &mips_fw->tpat) ||
 	    check_mips_fw_entry(bp->mips_firmware, &mips_fw->txp)) {
 		pr_err("Firmware file \"%s\" is invalid\n", mips_fw_file);
-		return -EINVAL;
+		rc = -EINVAL;
+		goto err_release_firmware;
 	}
 	if (bp->rv2p_firmware->size < sizeof(*rv2p_fw) ||
 	    check_fw_section(bp->rv2p_firmware, &rv2p_fw->proc1.rv2p, 8, true) ||
 	    check_fw_section(bp->rv2p_firmware, &rv2p_fw->proc2.rv2p, 8, true)) {
 		pr_err("Firmware file \"%s\" is invalid\n", rv2p_fw_file);
-		return -EINVAL;
+		rc = -EINVAL;
+		goto err_release_firmware;
 	}
+out:
+	return rc;
 
-	return 0;
+err_release_firmware:
+	release_firmware(bp->rv2p_firmware);
+	bp->rv2p_firmware = NULL;
+err_release_mips_firmware:
+	release_firmware(bp->mips_firmware);
+	goto out;
+}
+
+static int bnx2_request_firmware(struct bnx2 *bp)
+{
+	return bp->rv2p_firmware ? 0 : bnx2_request_uncached_firmware(bp);
 }
 
 static u32
@@ -6267,6 +6289,10 @@ bnx2_open(struct net_device *dev)
 	struct bnx2 *bp = netdev_priv(dev);
 	int rc;
 
+	rc = bnx2_request_firmware(bp);
+	if (rc < 0)
+		goto out;
+
 	netif_carrier_off(dev);
 
 	bnx2_set_power_state(bp, PCI_D0);
@@ -6327,8 +6353,8 @@ bnx2_open(struct net_device *dev)
 		netdev_info(dev, "using MSIX\n");
 
 	netif_tx_start_all_queues(dev);
-
-	return 0;
+out:
+	return rc;
 
 open_err:
 	bnx2_napi_disable(bp);
@@ -6336,7 +6362,8 @@ open_err:
 	bnx2_free_irq(bp);
 	bnx2_free_mem(bp);
 	bnx2_del_napi(bp);
-	return rc;
+	bnx2_release_firmware(bp);
+	goto out;
 }
 
 static void
@@ -8354,10 +8381,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	pci_set_drvdata(pdev, dev);
 
-	rc = bnx2_request_firmware(bp);
-	if (rc)
-		goto error;
-
 	memcpy(dev->dev_addr, bp->mac_addr, 6);
 	memcpy(dev->perm_addr, bp->mac_addr, 6);
 
@@ -8389,11 +8412,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	return 0;
 
 error:
-	if (bp->mips_firmware)
-		release_firmware(bp->mips_firmware);
-	if (bp->rv2p_firmware)
-		release_firmware(bp->rv2p_firmware);
-
 	if (bp->regview)
 		iounmap(bp->regview);
 	pci_release_regions(pdev);
@@ -8414,11 +8432,6 @@ bnx2_remove_one(struct pci_dev *pdev)
 	del_timer_sync(&bp->timer);
 	cancel_work_sync(&bp->reset_task);
 
-	if (bp->mips_firmware)
-		release_firmware(bp->mips_firmware);
-	if (bp->rv2p_firmware)
-		release_firmware(bp->rv2p_firmware);
-
 	if (bp->regview)
 		iounmap(bp->regview);
 
@@ -8429,6 +8442,8 @@ bnx2_remove_one(struct pci_dev *pdev)
 		bp->flags &= ~BNX2_FLAG_AER_ENABLED;
 	}
 
+	bnx2_release_firmware(bp);
+
 	free_netdev(dev);
 
 	pci_release_regions(pdev);
-- 
1.7.6.2

^ permalink raw reply related

* [PATCH next 2/7] 8139cp : removal of headers.
From: Francois Romieu @ 2011-09-30 10:37 UTC (permalink / raw)
  To: davem; +Cc: netdev
In-Reply-To: <20110930103604.GA26727@electric-eye.fr.zoreil.com>

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
 drivers/net/ethernet/realtek/8139cp.c |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
index c77d5af..60c8de5 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -55,8 +55,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/compiler.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/init.h>
@@ -65,7 +63,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/ethtool.h>
-#include <linux/gfp.h>
 #include <linux/mii.h>
 #include <linux/if_vlan.h>
 #include <linux/crc32.h>
@@ -73,10 +70,8 @@
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
-#include <linux/cache.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/uaccess.h>
 
 /* These identify the driver base version and may not be removed. */
 static char version[] =
-- 
1.7.6.2

^ permalink raw reply related

* [PATCH next 3/7] atm/iphase : removal of PCI space dereferences.
From: Francois Romieu @ 2011-09-30 10:37 UTC (permalink / raw)
  To: davem; +Cc: netdev
In-Reply-To: <20110930103604.GA26727@electric-eye.fr.zoreil.com>

Mostly PHY access and a few (ugly) debug statements for DMA control.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
 drivers/atm/iphase.c |  265 +++++++++++++++++++---------------
 drivers/atm/iphase.h |  391 ++++++++++++++++++++++++--------------------------
 2 files changed, 335 insertions(+), 321 deletions(-)

diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index cb90f7a..3d0c2b0 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -818,127 +818,152 @@ static void ia_hw_type(IADEV *iadev) {
 
 }
 
-static void IaFrontEndIntr(IADEV *iadev) {
-  volatile IA_SUNI *suni;
-  volatile ia_mb25_t *mb25;
-  volatile suni_pm7345_t *suni_pm7345;
-
-  if(iadev->phy_type & FE_25MBIT_PHY) {
-     mb25 = (ia_mb25_t*)iadev->phy;
-     iadev->carrier_detect =  Boolean(mb25->mb25_intr_status & MB25_IS_GSB);
-  } else if (iadev->phy_type & FE_DS3_PHY) {
-     suni_pm7345 = (suni_pm7345_t *)iadev->phy;
-     /* clear FRMR interrupts */
-     (void) suni_pm7345->suni_ds3_frm_intr_stat; 
-     iadev->carrier_detect =  
-           Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV));
-  } else if (iadev->phy_type & FE_E3_PHY ) {
-     suni_pm7345 = (suni_pm7345_t *)iadev->phy;
-     (void) suni_pm7345->suni_e3_frm_maint_intr_ind;
-     iadev->carrier_detect =
-           Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat&SUNI_E3_LOS));
-  }
-  else { 
-     suni = (IA_SUNI *)iadev->phy;
-     (void) suni->suni_rsop_status;
-     iadev->carrier_detect = Boolean(!(suni->suni_rsop_status & SUNI_LOSV));
-  }
-  if (iadev->carrier_detect)
-    printk("IA: SUNI carrier detected\n");
-  else
-    printk("IA: SUNI carrier lost signal\n"); 
-  return;
+static u32 ia_phy_read32(struct iadev_priv *ia, unsigned int reg)
+{
+	return readl(ia->phy + (reg >> 2));
+}
+
+static void ia_phy_write32(struct iadev_priv *ia, unsigned int reg, u32 val)
+{
+	writel(val, ia->phy + (reg >> 2));
+}
+
+static void ia_frontend_intr(struct iadev_priv *iadev)
+{
+	u32 status;
+
+	if (iadev->phy_type & FE_25MBIT_PHY) {
+		status = ia_phy_read32(iadev, MB25_INTR_STATUS);
+		iadev->carrier_detect = (status & MB25_IS_GSB) ? 1 : 0;
+	} else if (iadev->phy_type & FE_DS3_PHY) {
+		ia_phy_read32(iadev, SUNI_DS3_FRM_INTR_STAT);
+		status = ia_phy_read32(iadev, SUNI_DS3_FRM_STAT);
+		iadev->carrier_detect = (status & SUNI_DS3_LOSV) ? 0 : 1;
+	} else if (iadev->phy_type & FE_E3_PHY) {
+		ia_phy_read32(iadev, SUNI_E3_FRM_MAINT_INTR_IND);
+		status = ia_phy_read32(iadev, SUNI_E3_FRM_FRAM_INTR_IND_STAT);
+		iadev->carrier_detect = (status & SUNI_E3_LOS) ? 0 : 1;
+	} else {
+		status = ia_phy_read32(iadev, SUNI_RSOP_STATUS);
+		iadev->carrier_detect = (status & SUNI_LOSV) ? 0 : 1;
+	}
+
+	printk(KERN_INFO "IA: SUNI carrier %s\n",
+		iadev->carrier_detect ? "detected" : "lost signal");
 }
 
-static void ia_mb25_init (IADEV *iadev)
+static void ia_mb25_init(struct iadev_priv *iadev)
 {
-   volatile ia_mb25_t  *mb25 = (ia_mb25_t*)iadev->phy;
 #if 0
    mb25->mb25_master_ctrl = MB25_MC_DRIC | MB25_MC_DREC | MB25_MC_ENABLED;
 #endif
-   mb25->mb25_master_ctrl = MB25_MC_DRIC | MB25_MC_DREC;
-   mb25->mb25_diag_control = 0;
-   /*
-    * Initialize carrier detect state
-    */
-   iadev->carrier_detect =  Boolean(mb25->mb25_intr_status & MB25_IS_GSB);
-   return;
-}                   
+	ia_phy_write32(iadev, MB25_MASTER_CTRL, MB25_MC_DRIC | MB25_MC_DREC);
+	ia_phy_write32(iadev, MB25_DIAG_CONTROL, 0);
+
+	iadev->carrier_detect =
+		(ia_phy_read32(iadev, MB25_INTR_STATUS) & MB25_IS_GSB) ? 1 : 0;
+}
 
-static void ia_suni_pm7345_init (IADEV *iadev)
+struct ia_reg {
+	u16 reg;
+	u16 val;
+};
+
+static void ia_phy_write(struct iadev_priv *iadev,
+			 const struct ia_reg *regs, int len)
 {
-   volatile suni_pm7345_t *suni_pm7345 = (suni_pm7345_t *)iadev->phy;
-   if (iadev->phy_type & FE_DS3_PHY)
-   {
-      iadev->carrier_detect = 
-          Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV)); 
-      suni_pm7345->suni_ds3_frm_intr_enbl = 0x17;
-      suni_pm7345->suni_ds3_frm_cfg = 1;
-      suni_pm7345->suni_ds3_tran_cfg = 1;
-      suni_pm7345->suni_config = 0;
-      suni_pm7345->suni_splr_cfg = 0;
-      suni_pm7345->suni_splt_cfg = 0;
-   }
-   else 
-   {
-      iadev->carrier_detect = 
-          Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat & SUNI_E3_LOS));
-      suni_pm7345->suni_e3_frm_fram_options = 0x4;
-      suni_pm7345->suni_e3_frm_maint_options = 0x20;
-      suni_pm7345->suni_e3_frm_fram_intr_enbl = 0x1d;
-      suni_pm7345->suni_e3_frm_maint_intr_enbl = 0x30;
-      suni_pm7345->suni_e3_tran_stat_diag_options = 0x0;
-      suni_pm7345->suni_e3_tran_fram_options = 0x1;
-      suni_pm7345->suni_config = SUNI_PM7345_E3ENBL;
-      suni_pm7345->suni_splr_cfg = 0x41;
-      suni_pm7345->suni_splt_cfg = 0x41;
-   } 
-   /*
-    * Enable RSOP loss of signal interrupt.
-    */
-   suni_pm7345->suni_intr_enbl = 0x28;
- 
-   /*
-    * Clear error counters
-    */
-   suni_pm7345->suni_id_reset = 0;
-
-   /*
-    * Clear "PMCTST" in master test register.
-    */
-   suni_pm7345->suni_master_test = 0;
-
-   suni_pm7345->suni_rxcp_ctrl = 0x2c;
-   suni_pm7345->suni_rxcp_fctrl = 0x81;
- 
-   suni_pm7345->suni_rxcp_idle_pat_h1 =
-   	suni_pm7345->suni_rxcp_idle_pat_h2 =
-   	suni_pm7345->suni_rxcp_idle_pat_h3 = 0;
-   suni_pm7345->suni_rxcp_idle_pat_h4 = 1;
- 
-   suni_pm7345->suni_rxcp_idle_mask_h1 = 0xff;
-   suni_pm7345->suni_rxcp_idle_mask_h2 = 0xff;
-   suni_pm7345->suni_rxcp_idle_mask_h3 = 0xff;
-   suni_pm7345->suni_rxcp_idle_mask_h4 = 0xfe;
- 
-   suni_pm7345->suni_rxcp_cell_pat_h1 =
-   	suni_pm7345->suni_rxcp_cell_pat_h2 =
-   	suni_pm7345->suni_rxcp_cell_pat_h3 = 0;
-   suni_pm7345->suni_rxcp_cell_pat_h4 = 1;
- 
-   suni_pm7345->suni_rxcp_cell_mask_h1 =
-   	suni_pm7345->suni_rxcp_cell_mask_h2 =
-   	suni_pm7345->suni_rxcp_cell_mask_h3 =
-   	suni_pm7345->suni_rxcp_cell_mask_h4 = 0xff;
- 
-   suni_pm7345->suni_txcp_ctrl = 0xa4;
-   suni_pm7345->suni_txcp_intr_en_sts = 0x10;
-   suni_pm7345->suni_txcp_idle_pat_h5 = 0x55;
- 
-   suni_pm7345->suni_config &= ~(SUNI_PM7345_LLB |
-                                 SUNI_PM7345_CLB |
-                                 SUNI_PM7345_DLB |
-                                  SUNI_PM7345_PLB);
+	while (len--) {
+		ia_phy_write32(iadev, regs->reg, regs->val);
+		regs++;
+	}
+}
+
+static void ia_suni_pm7345_init_ds3(struct iadev_priv *iadev)
+{
+	static const struct ia_reg suni_ds3_init [] = {
+		{ SUNI_DS3_FRM_INTR_ENBL,	0x17 },
+		{ SUNI_DS3_FRM_CFG,		0x01 },
+		{ SUNI_DS3_TRAN_CFG,		0x01 },
+		{ SUNI_CONFIG,			0 },
+		{ SUNI_SPLR_CFG,		0 },
+		{ SUNI_SPLT_CFG,		0 }
+	};
+	u32 status;
+
+	status = ia_phy_read32(iadev, SUNI_DS3_FRM_STAT);
+	iadev->carrier_detect = (status & SUNI_DS3_LOSV) ? 0 : 1;
+
+	ia_phy_write(iadev, suni_ds3_init, ARRAY_SIZE(suni_ds3_init));
+}
+
+static void ia_suni_pm7345_init_e3(struct iadev_priv *iadev)
+{
+	static const struct ia_reg suni_e3_init [] = {
+		{ SUNI_E3_FRM_FRAM_OPTIONS,		0x04 },
+		{ SUNI_E3_FRM_MAINT_OPTIONS,		0x20 },
+		{ SUNI_E3_FRM_FRAM_INTR_ENBL,		0x1d },
+		{ SUNI_E3_FRM_MAINT_INTR_ENBL,		0x30 },
+		{ SUNI_E3_TRAN_STAT_DIAG_OPTIONS,	0 },
+		{ SUNI_E3_TRAN_FRAM_OPTIONS,		0x01 },
+		{ SUNI_CONFIG,				SUNI_PM7345_E3ENBL },
+		{ SUNI_SPLR_CFG,			0x41 },
+		{ SUNI_SPLT_CFG,			0x41 }
+	};
+	u32 status;
+
+	status = ia_phy_read32(iadev, SUNI_E3_FRM_FRAM_INTR_IND_STAT);
+	iadev->carrier_detect = (status & SUNI_E3_LOS) ? 0 : 1;
+	ia_phy_write(iadev, suni_e3_init, ARRAY_SIZE(suni_e3_init));
+}
+
+static void ia_suni_pm7345_init(struct iadev_priv *iadev)
+{
+	static const struct ia_reg suni_init [] = {
+		/* Enable RSOP loss of signal interrupt. */
+		{ SUNI_INTR_ENBL,		0x28 },
+		/* Clear error counters. */
+		{ SUNI_ID_RESET,		0 },
+		/* Clear "PMCTST" in master test register. */
+		{ SUNI_MASTER_TEST,		0 },
+
+		{ SUNI_RXCP_CTRL,		0x2c },
+		{ SUNI_RXCP_FCTRL,		0x81 },
+
+		{ SUNI_RXCP_IDLE_PAT_H1,	0 },
+		{ SUNI_RXCP_IDLE_PAT_H2,	0 },
+		{ SUNI_RXCP_IDLE_PAT_H3,	0 },
+		{ SUNI_RXCP_IDLE_PAT_H4,	0x01 },
+
+		{ SUNI_RXCP_IDLE_MASK_H1,	0xff },
+		{ SUNI_RXCP_IDLE_MASK_H2,	0xff },
+		{ SUNI_RXCP_IDLE_MASK_H3,	0xff },
+		{ SUNI_RXCP_IDLE_MASK_H4,	0xfe },
+
+		{ SUNI_RXCP_CELL_PAT_H1,	0 },
+		{ SUNI_RXCP_CELL_PAT_H2,	0 },
+		{ SUNI_RXCP_CELL_PAT_H3,	0 },
+		{ SUNI_RXCP_CELL_PAT_H4,	0x01 },
+
+		{ SUNI_RXCP_CELL_MASK_H1,	0xff },
+		{ SUNI_RXCP_CELL_MASK_H2,	0xff },
+		{ SUNI_RXCP_CELL_MASK_H3,	0xff },
+		{ SUNI_RXCP_CELL_MASK_H4,	0xff },
+
+		{ SUNI_TXCP_CTRL,		0xa4 },
+		{ SUNI_TXCP_INTR_EN_STS,	0x10 },
+		{ SUNI_TXCP_IDLE_PAT_H5,	0x55 }
+	};
+
+	if (iadev->phy_type & FE_DS3_PHY)
+		ia_suni_pm7345_init_ds3(iadev);
+	else
+		ia_suni_pm7345_init_e3(iadev);
+
+	ia_phy_write(iadev, suni_init, ARRAY_SIZE(suni_init));
+
+	ia_phy_write32(iadev, SUNI_CONFIG, ia_phy_read32(iadev, SUNI_CONFIG) &
+		~(SUNI_PM7345_LLB | SUNI_PM7345_CLB |
+		  SUNI_PM7345_DLB | SUNI_PM7345_PLB));
 #ifdef __SNMP__
    suni_pm7345->suni_rxcp_intr_en_sts |= SUNI_OOCDE;
 #endif /* __SNMP__ */
@@ -1425,10 +1450,10 @@ static int rx_init(struct atm_dev *dev)
 	       iadev->dma + IPHASE5575_RX_LIST_ADDR);  
 	IF_INIT(printk("Tx Dle list addr: 0x%p value: 0x%0x\n",
                       iadev->dma+IPHASE5575_TX_LIST_ADDR,
-                      *(u32*)(iadev->dma+IPHASE5575_TX_LIST_ADDR));  
+                      readl(iadev->dma + IPHASE5575_TX_LIST_ADDR));
 	printk("Rx Dle list addr: 0x%p value: 0x%0x\n",
                       iadev->dma+IPHASE5575_RX_LIST_ADDR,
-                      *(u32*)(iadev->dma+IPHASE5575_RX_LIST_ADDR));)  
+                      readl(iadev->dma + IPHASE5575_RX_LIST_ADDR));)
   
 	writew(0xffff, iadev->reass_reg+REASS_MASK_REG);  
 	writew(0, iadev->reass_reg+MODE_REG);  
@@ -2208,7 +2233,7 @@ static irqreturn_t ia_int(int irq, void *dev_id)
 	if (status & STAT_DLERINT)  
 	{  
 	   /* Clear this bit by writing a 1 to it. */  
-	   *(u_int *)(iadev->reg+IPHASE5575_BUS_STATUS_REG) = STAT_DLERINT;
+	   writel(STAT_DLERINT, iadev->reg + IPHASE5575_BUS_STATUS_REG);
 	   rx_dle_intr(dev);  
 	}  
 	if (status & STAT_SEGINT)  
@@ -2219,13 +2244,13 @@ static irqreturn_t ia_int(int irq, void *dev_id)
 	}  
 	if (status & STAT_DLETINT)  
 	{  
-	   *(u_int *)(iadev->reg+IPHASE5575_BUS_STATUS_REG) = STAT_DLETINT;  
+	   writel(STAT_DLETINT, iadev->reg + IPHASE5575_BUS_STATUS_REG);
 	   tx_dle_intr(dev);  
 	}  
 	if (status & (STAT_FEINT | STAT_ERRINT | STAT_MARKINT))  
 	{  
            if (status & STAT_FEINT) 
-               IaFrontEndIntr(iadev);
+               ia_frontend_intr(iadev);
 	}  
    }
    return IRQ_RETVAL(handled);
@@ -2556,7 +2581,7 @@ static int __devinit ia_start(struct atm_dev *dev)
 				goto err_free_rx;
 		}
 		/* Get iadev->carrier_detect status */
-		IaFrontEndIntr(iadev);
+		ia_frontend_intr(iadev);
 	}
 	return 0;
 
@@ -2827,7 +2852,7 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
 
          case 0xb:
 	    if (!capable(CAP_NET_ADMIN)) return -EPERM;
-            IaFrontEndIntr(iadev);
+            ia_frontend_intr(iadev);
             break;
          case 0xa:
 	    if (!capable(CAP_NET_ADMIN)) return -EPERM;
diff --git a/drivers/atm/iphase.h b/drivers/atm/iphase.h
index 077735e..6a0955e 100644
--- a/drivers/atm/iphase.h
+++ b/drivers/atm/iphase.h
@@ -889,79 +889,71 @@ typedef struct ia_rtn_q {
 } IARTN_Q;
 
 #define SUNI_LOSV   	0x04
-typedef struct {
-        u32   suni_master_reset;      /* SUNI Master Reset and Identity     */
-        u32   suni_master_config;     /* SUNI Master Configuration          */
-        u32   suni_master_intr_stat;  /* SUNI Master Interrupt Status       */
-        u32   suni_reserved1;         /* Reserved                           */
-        u32   suni_master_clk_monitor;/* SUNI Master Clock Monitor          */
-        u32   suni_master_control;    /* SUNI Master Clock Monitor          */
-        u32   suni_reserved2[10];     /* Reserved                           */
-
-        u32   suni_rsop_control;      /* RSOP Control/Interrupt Enable      */
-        u32   suni_rsop_status;       /* RSOP Status/Interrupt States       */
-        u32   suni_rsop_section_bip8l;/* RSOP Section BIP-8 LSB             */
-        u32   suni_rsop_section_bip8m;/* RSOP Section BIP-8 MSB             */
-
-        u32   suni_tsop_control;      /* TSOP Control                       */
-        u32   suni_tsop_diag;         /* TSOP Disgnostics                   */
-        u32   suni_tsop_reserved[2];  /* TSOP Reserved                      */
-
-        u32   suni_rlop_cs;           /* RLOP Control/Status                */
-        u32   suni_rlop_intr;         /* RLOP Interrupt Enable/Status       */
-        u32   suni_rlop_line_bip24l;  /* RLOP Line BIP-24 LSB               */
-        u32   suni_rlop_line_bip24;   /* RLOP Line BIP-24                   */
-        u32   suni_rlop_line_bip24m;  /* RLOP Line BIP-24 MSB               */
-        u32   suni_rlop_line_febel;   /* RLOP Line FEBE LSB                 */
-        u32   suni_rlop_line_febe;    /* RLOP Line FEBE                     */
-        u32   suni_rlop_line_febem;   /* RLOP Line FEBE MSB                 */
-
-        u32   suni_tlop_control;      /* TLOP Control                       */
-        u32   suni_tlop_disg;         /* TLOP Disgnostics                   */
-        u32   suni_tlop_reserved[14]; /* TLOP Reserved                      */
-
-        u32   suni_rpop_cs;           /* RPOP Status/Control                */
-        u32   suni_rpop_intr;         /* RPOP Interrupt/Status              */
-        u32   suni_rpop_reserved;     /* RPOP Reserved                      */
-        u32   suni_rpop_intr_ena;     /* RPOP Interrupt Enable              */
-        u32   suni_rpop_reserved1[3]; /* RPOP Reserved                      */
-        u32   suni_rpop_path_sig;     /* RPOP Path Signal Label             */
-        u32   suni_rpop_bip8l;        /* RPOP Path BIP-8 LSB                */
-        u32   suni_rpop_bip8m;        /* RPOP Path BIP-8 MSB                */
-        u32   suni_rpop_febel;        /* RPOP Path FEBE LSB                 */
-        u32   suni_rpop_febem;        /* RPOP Path FEBE MSB                 */
-        u32   suni_rpop_reserved2[4]; /* RPOP Reserved                      */
-
-        u32   suni_tpop_cntrl_daig;   /* TPOP Control/Disgnostics           */
-        u32   suni_tpop_pointer_ctrl; /* TPOP Pointer Control               */
-        u32   suni_tpop_sourcer_ctrl; /* TPOP Source Control                */
-        u32   suni_tpop_reserved1[2]; /* TPOP Reserved                      */
-        u32   suni_tpop_arb_prtl;     /* TPOP Arbitrary Pointer LSB         */
-        u32   suni_tpop_arb_prtm;     /* TPOP Arbitrary Pointer MSB         */
-        u32   suni_tpop_reserved2;    /* TPOP Reserved                      */
-        u32   suni_tpop_path_sig;     /* TPOP Path Signal Lable             */
-        u32   suni_tpop_path_status;  /* TPOP Path Status                   */
-        u32   suni_tpop_reserved3[6]; /* TPOP Reserved                      */              
-
-        u32   suni_racp_cs;           /* RACP Control/Status                */
-        u32   suni_racp_intr;         /* RACP Interrupt Enable/Status       */
-        u32   suni_racp_hdr_pattern;  /* RACP Match Header Pattern          */
-        u32   suni_racp_hdr_mask;     /* RACP Match Header Mask             */
-        u32   suni_racp_corr_hcs;     /* RACP Correctable HCS Error Count   */
-        u32   suni_racp_uncorr_hcs;   /* RACP Uncorrectable HCS Error Count */
-        u32   suni_racp_reserved[10]; /* RACP Reserved                      */
-
-        u32   suni_tacp_control;      /* TACP Control                       */
-        u32   suni_tacp_idle_hdr_pat; /* TACP Idle Cell Header Pattern      */
-        u32   suni_tacp_idle_pay_pay; /* TACP Idle Cell Payld Octet Pattern */
-        u32   suni_tacp_reserved[5];  /* TACP Reserved                      */
-
-        u32   suni_reserved3[24];     /* Reserved                           */
-
-        u32   suni_master_test;       /* SUNI Master Test                   */
-        u32   suni_reserved_test;     /* SUNI Reserved for Test             */
-} IA_SUNI;
-
+enum ia_suni {
+	SUNI_MASTER_RESET	= 0x000, /* SUNI Master Reset and Identity   */
+	SUNI_MASTER_CONFIG	= 0x004, /* SUNI Master Configuration        */
+	SUNI_MASTER_INTR_STAT	= 0x008, /* SUNI Master Interrupt Status     */
+	SUNI_RESERVED1		= 0x00c, /* Reserved                         */
+	SUNI_MASTER_CLK_MONITOR	= 0x010, /* SUNI Master Clock Monitor        */
+	SUNI_MASTER_CONTROL	= 0x014, /* SUNI Master Clock Monitor        */
+					 /* Reserved (10)                    */
+	SUNI_RSOP_CONTROL	= 0x040, /* RSOP Control/Interrupt Enable    */
+	SUNI_RSOP_STATUS	= 0x044, /* RSOP Status/Interrupt States     */
+	SUNI_RSOP_SECTION_BIP8L	= 0x048, /* RSOP Section BIP-8 LSB           */
+	SUNI_RSOP_SECTION_BIP8M	= 0x04c, /* RSOP Section BIP-8 MSB           */
+
+	SUNI_TSOP_CONTROL	= 0x050, /* TSOP Control                     */
+	SUNI_TSOP_DIAG		= 0x054, /* TSOP Disgnostics                 */
+					 /* Reserved (2)                     */
+	SUNI_RLOP_CS		= 0x060, /* RLOP Control/Status              */
+	SUNI_RLOP_INTR		= 0x064, /* RLOP Interrupt Enable/Status     */
+	SUNI_RLOP_LINE_BIP24L	= 0x068, /* RLOP Line BIP-24 LSB             */
+	SUNI_RLOP_LINE_BIP24	= 0x06c, /* RLOP Line BIP-24                 */
+	SUNI_RLOP_LINE_BIP24M	= 0x070, /* RLOP Line BIP-24 MSB             */
+	SUNI_RLOP_LINE_FEBEL	= 0x074, /* RLOP Line FEBE LSB               */
+	SUNI_RLOP_LINE_FEBE	= 0x078, /* RLOP Line FEBE                   */
+	SUNI_RLOP_LINE_FEBEM	= 0x07c, /* RLOP Line FEBE MSB               */
+
+	SUNI_TLOP_CONTROL	= 0x080, /* TLOP Control                     */
+	SUNI_TLOP_DISG		= 0x084, /* TLOP Disgnostics                 */
+					 /* Reserved (14)                    */
+	SUNI_RPOP_CS		= 0x0c0, /* RPOP Status/Control              */
+	SUNI_RPOP_INTR		= 0x0c4, /* RPOP Interrupt/Status            */
+	SUNI_RPOP_RESERVED	= 0x0c8, /* RPOP Reserved                    */
+	SUNI_RPOP_INTR_ENA	= 0x0cc, /* RPOP Interrupt Enable            */
+					 /* Reserved (3)                     */
+	SUNI_RPOP_PATH_SIG	= 0x0dc, /* RPOP Path Signal Label           */
+	SUNI_RPOP_BIP8L		= 0x0e0, /* RPOP Path BIP-8 LSB              */
+	SUNI_RPOP_BIP8M		= 0x0e4, /* RPOP Path BIP-8 MSB              */
+	SUNI_RPOP_FEBEL		= 0x0e8, /* RPOP Path FEBE LSB               */
+	SUNI_RPOP_FEBEM		= 0x0ec, /* RPOP Path FEBE MSB               */
+					 /* Reserved (4)                     */
+	SUNI_TPOP_CNTRL_DAIG	= 0x100, /* TPOP Control/Disgnostics         */
+	SUNI_TPOP_POINTER_CTRL	= 0x104, /* TPOP Pointer Control             */
+	SUNI_TPOP_SOURCER_CTRL	= 0x108, /* TPOP Source Control              */
+					 /* Reserved (2)                     */
+	SUNI_TPOP_ARB_PRTL	= 0x114, /* TPOP Arbitrary Pointer LSB       */
+	SUNI_TPOP_ARB_PRTM	= 0x118, /* TPOP Arbitrary Pointer MSB       */
+	SUNI_TPOP_RESERVED2	= 0x11c, /* TPOP Reserved                    */
+	SUNI_TPOP_PATH_SIG	= 0x120, /* TPOP Path Signal Lable           */
+	SUNI_TPOP_PATH_STATUS	= 0x124, /* TPOP Path Status                 */
+					 /* Reserved (6)                     */
+	SUNI_RACP_CS		= 0x140, /* RACP Control/Status              */
+	SUNI_RACP_INTR		= 0x144, /* RACP Interrupt Enable/Status     */
+	SUNI_RACP_HDR_PATTERN	= 0x148, /* RACP Match Header Pattern        */
+	SUNI_RACP_HDR_MASK	= 0x14c, /* RACP Match Header Mask           */
+	SUNI_RACP_CORR_HCS	= 0x150, /* RACP Correctable HCS Error Count */
+	SUNI_RACP_UNCORR_HCS	= 0x154, /* RACP Uncorrectable HCS Err Count */
+					 /* Reserved (10)                    */
+	SUNI_TACP_CONTROL	= 0x180, /* TACP Control                     */
+	SUNI_TACP_IDLE_HDR_PAT	= 0x184, /* TACP Idle Cell Header Pattern    */
+	SUNI_TACP_IDLE_PAY_PAY	= 0x188, /* TACP Idle Cell Payld Octet Patrn */
+					 /* Reserved (5)                     */
+					 /* Reserved (24)                    */
+	/* FIXME: unused but name conflicts.
+	 * SUNI_MASTER_TEST	= 0x200,    SUNI Master Test                 */
+	SUNI_RESERVED_TEST	= 0x204  /* SUNI Reserved for Test           */
+};
 
 typedef struct _SUNI_STATS_
 {
@@ -993,13 +985,11 @@ typedef struct _SUNI_STATS_
    u32 racp_uchcs_count;            // uncorrectable HCS error count
 } IA_SUNI_STATS; 
 
-typedef struct iadev_t {  
+typedef struct iadev_priv {
 	/*-----base pointers into (i)chipSAR+ address space */   
-	u32 __iomem *phy;		/* base pointer into phy(SUNI) */  
-	u32 __iomem *dma;		/* base pointer into DMA control   
-						registers */  
-	u32 __iomem *reg;		/* base pointer to SAR registers  
-					   - Bus Interface Control Regs */  
+	u32 __iomem *phy;	/* Base pointer into phy (SUNI). */
+	u32 __iomem *dma;	/* Base pointer into DMA control registers. */
+	u32 __iomem *reg;	/* Base pointer to SAR registers. */
 	u32 __iomem *seg_reg;		/* base pointer to segmentation engine  
 						internal registers */  
 	u32 __iomem *reass_reg;		/* base pointer to reassemble engine  
@@ -1071,14 +1061,14 @@ typedef struct iadev_t {
 #define INPH_IA_VCC(v) ((struct ia_vcc *) (v)->dev_data)  
 
 /******************* IDT77105 25MB/s PHY DEFINE *****************************/
-typedef struct {
-	u_int	mb25_master_ctrl;	/* Master control		     */
-	u_int	mb25_intr_status;	/* Interrupt status		     */
-	u_int	mb25_diag_control;	/* Diagnostic control		     */
-	u_int	mb25_led_hec;		/* LED driver and HEC status/control */
-	u_int	mb25_low_byte_counter;	/* Low byte counter		     */
-	u_int	mb25_high_byte_counter;	/* High byte counter		     */
-} ia_mb25_t;
+enum ia_mb25 {
+	MB25_MASTER_CTRL	= 0x00, /* Master control		     */
+	MB25_INTR_STATUS	= 0x04,	/* Interrupt status		     */
+	MB25_DIAG_CONTROL	= 0x08,	/* Diagnostic control		     */
+	MB25_LED_HEC		= 0x0c,	/* LED driver and HEC status/control */
+	MB25_LOW_BYTE_COUNTER	= 0x10,
+	MB25_HIGH_BYTE_COUNTER	= 0x14
+};
 
 /*
  * Master Control
@@ -1127,122 +1117,121 @@ typedef struct {
 #define FE_E3_PHY       0x0090          /* E3 */
 		     
 /*********************** SUNI_PM7345 PHY DEFINE HERE *********************/
-typedef struct _suni_pm7345_t
-{
-    u_int suni_config;     /* SUNI Configuration */
-    u_int suni_intr_enbl;  /* SUNI Interrupt Enable */
-    u_int suni_intr_stat;  /* SUNI Interrupt Status */
-    u_int suni_control;    /* SUNI Control */
-    u_int suni_id_reset;   /* SUNI Reset and Identity */
-    u_int suni_data_link_ctrl;
-    u_int suni_rboc_conf_intr_enbl;
-    u_int suni_rboc_stat;
-    u_int suni_ds3_frm_cfg;
-    u_int suni_ds3_frm_intr_enbl;
-    u_int suni_ds3_frm_intr_stat;
-    u_int suni_ds3_frm_stat;
-    u_int suni_rfdl_cfg;
-    u_int suni_rfdl_enbl_stat;
-    u_int suni_rfdl_stat;
-    u_int suni_rfdl_data;
-    u_int suni_pmon_chng;
-    u_int suni_pmon_intr_enbl_stat;
-    u_int suni_reserved1[0x13-0x11];
-    u_int suni_pmon_lcv_evt_cnt_lsb;
-    u_int suni_pmon_lcv_evt_cnt_msb;
-    u_int suni_pmon_fbe_evt_cnt_lsb;
-    u_int suni_pmon_fbe_evt_cnt_msb;
-    u_int suni_pmon_sez_det_cnt_lsb;
-    u_int suni_pmon_sez_det_cnt_msb;
-    u_int suni_pmon_pe_evt_cnt_lsb;
-    u_int suni_pmon_pe_evt_cnt_msb;
-    u_int suni_pmon_ppe_evt_cnt_lsb;
-    u_int suni_pmon_ppe_evt_cnt_msb;
-    u_int suni_pmon_febe_evt_cnt_lsb;
-    u_int suni_pmon_febe_evt_cnt_msb;
-    u_int suni_ds3_tran_cfg;
-    u_int suni_ds3_tran_diag;
-    u_int suni_reserved2[0x23-0x21];
-    u_int suni_xfdl_cfg;
-    u_int suni_xfdl_intr_st;
-    u_int suni_xfdl_xmit_data;
-    u_int suni_xboc_code;
-    u_int suni_splr_cfg;
-    u_int suni_splr_intr_en;
-    u_int suni_splr_intr_st;
-    u_int suni_splr_status;
-    u_int suni_splt_cfg;
-    u_int suni_splt_cntl;
-    u_int suni_splt_diag_g1;
-    u_int suni_splt_f1;
-    u_int suni_cppm_loc_meters;
-    u_int suni_cppm_chng_of_cppm_perf_meter;
-    u_int suni_cppm_b1_err_cnt_lsb;
-    u_int suni_cppm_b1_err_cnt_msb;
-    u_int suni_cppm_framing_err_cnt_lsb;
-    u_int suni_cppm_framing_err_cnt_msb;
-    u_int suni_cppm_febe_cnt_lsb;
-    u_int suni_cppm_febe_cnt_msb;
-    u_int suni_cppm_hcs_err_cnt_lsb;
-    u_int suni_cppm_hcs_err_cnt_msb;
-    u_int suni_cppm_idle_un_cell_cnt_lsb;
-    u_int suni_cppm_idle_un_cell_cnt_msb;
-    u_int suni_cppm_rcv_cell_cnt_lsb;
-    u_int suni_cppm_rcv_cell_cnt_msb;
-    u_int suni_cppm_xmit_cell_cnt_lsb;
-    u_int suni_cppm_xmit_cell_cnt_msb;
-    u_int suni_rxcp_ctrl;
-    u_int suni_rxcp_fctrl;
-    u_int suni_rxcp_intr_en_sts;
-    u_int suni_rxcp_idle_pat_h1;
-    u_int suni_rxcp_idle_pat_h2;
-    u_int suni_rxcp_idle_pat_h3;
-    u_int suni_rxcp_idle_pat_h4;
-    u_int suni_rxcp_idle_mask_h1;
-    u_int suni_rxcp_idle_mask_h2;
-    u_int suni_rxcp_idle_mask_h3;
-    u_int suni_rxcp_idle_mask_h4;
-    u_int suni_rxcp_cell_pat_h1;
-    u_int suni_rxcp_cell_pat_h2;
-    u_int suni_rxcp_cell_pat_h3;
-    u_int suni_rxcp_cell_pat_h4;
-    u_int suni_rxcp_cell_mask_h1;
-    u_int suni_rxcp_cell_mask_h2;
-    u_int suni_rxcp_cell_mask_h3;
-    u_int suni_rxcp_cell_mask_h4;
-    u_int suni_rxcp_hcs_cs;
-    u_int suni_rxcp_lcd_cnt_threshold;
-    u_int suni_reserved3[0x57-0x54];
-    u_int suni_txcp_ctrl;
-    u_int suni_txcp_intr_en_sts;
-    u_int suni_txcp_idle_pat_h1;
-    u_int suni_txcp_idle_pat_h2;
-    u_int suni_txcp_idle_pat_h3;
-    u_int suni_txcp_idle_pat_h4;
-    u_int suni_txcp_idle_pat_h5;
-    u_int suni_txcp_idle_payload;
-    u_int suni_e3_frm_fram_options;
-    u_int suni_e3_frm_maint_options;
-    u_int suni_e3_frm_fram_intr_enbl;
-    u_int suni_e3_frm_fram_intr_ind_stat;
-    u_int suni_e3_frm_maint_intr_enbl;
-    u_int suni_e3_frm_maint_intr_ind;
-    u_int suni_e3_frm_maint_stat;
-    u_int suni_reserved4;
-    u_int suni_e3_tran_fram_options;
-    u_int suni_e3_tran_stat_diag_options;
-    u_int suni_e3_tran_bip_8_err_mask;
-    u_int suni_e3_tran_maint_adapt_options;
-    u_int suni_ttb_ctrl;
-    u_int suni_ttb_trail_trace_id_stat;
-    u_int suni_ttb_ind_addr;
-    u_int suni_ttb_ind_data;
-    u_int suni_ttb_exp_payload_type;
-    u_int suni_ttb_payload_type_ctrl_stat;
-    u_int suni_pad5[0x7f-0x71];
-    u_int suni_master_test;
-    u_int suni_pad6[0xff-0x80];
-}suni_pm7345_t;
+enum suni_pm7345 {
+	SUNI_CONFIG			= 0x000, /* SUNI Configuration */
+	SUNI_INTR_ENBL			= 0x004, /* SUNI Interrupt Enable */
+	SUNI_INTR_STAT			= 0x008, /* SUNI Interrupt Status */
+	SUNI_CONTROL			= 0x00c, /* SUNI Control */
+	SUNI_ID_RESET			= 0x010, /* SUNI Reset and Identity */
+	SUNI_DATA_LINK_CTRL		= 0x014,
+	SUNI_RBOC_CONF_INTR_ENBL	= 0x018,
+	SUNI_RBOC_STAT			= 0x01c,
+	SUNI_DS3_FRM_CFG		= 0x020,
+	SUNI_DS3_FRM_INTR_ENBL		= 0x024,
+	SUNI_DS3_FRM_INTR_STAT		= 0x028,
+	SUNI_DS3_FRM_STAT		= 0x02c,
+	SUNI_RFDL_CFG			= 0x030,
+	SUNI_RFDL_ENBL_STAT		= 0x034,
+	SUNI_RFDL_STAT			= 0x038,
+	SUNI_RFDL_DATA			= 0x03c,
+	SUNI_PMON_CHNG			= 0x040,
+	SUNI_PMON_INTR_ENBL_STAT	= 0x044,
+	/* SUNI_RESERVED1 (0x13 - 0x11) */
+	SUNI_PMON_LCV_EVT_CNT_LSB	= 0x050,
+	SUNI_PMON_LCV_EVT_CNT_MSB	= 0x054,
+	SUNI_PMON_FBE_EVT_CNT_LSB	= 0x058,
+	SUNI_PMON_FBE_EVT_CNT_MSB	= 0x05c,
+	SUNI_PMON_SEZ_DET_CNT_LSB	= 0x060,
+	SUNI_PMON_SEZ_DET_CNT_MSB	= 0x064,
+	SUNI_PMON_PE_EVT_CNT_LSB	= 0x068,
+	SUNI_PMON_PE_EVT_CNT_MSB	= 0x06c,
+	SUNI_PMON_PPE_EVT_CNT_LSB	= 0x070,
+	SUNI_PMON_PPE_EVT_CNT_MSB	= 0x074,
+	SUNI_PMON_FEBE_EVT_CNT_LSB	= 0x078,
+	SUNI_PMON_FEBE_EVT_CNT_MSB	= 0x07c,
+	SUNI_DS3_TRAN_CFG		= 0x080,
+	SUNI_DS3_TRAN_DIAG		= 0x084,
+	/* SUNI_RESERVED2 (0x23 - 0x21) */
+	SUNI_XFDL_CFG			= 0x090,
+	SUNI_XFDL_INTR_ST		= 0x094,
+	SUNI_XFDL_XMIT_DATA		= 0x098,
+	SUNI_XBOC_CODE			= 0x09c,
+	SUNI_SPLR_CFG			= 0x0a0,
+	SUNI_SPLR_INTR_EN		= 0x0a4,
+	SUNI_SPLR_INTR_ST		= 0x0a8,
+	SUNI_SPLR_STATUS		= 0x0ac,
+	SUNI_SPLT_CFG			= 0x0b0,
+	SUNI_SPLT_CNTL			= 0x0b4,
+	SUNI_SPLT_DIAG_G1		= 0x0b8,
+	SUNI_SPLT_F1			= 0x0bc,
+	SUNI_CPPM_LOC_METERS		= 0x0c0,
+	SUNI_CPPM_CHG_OF_CPPM_PERF_METR	= 0x0c4,
+	SUNI_CPPM_B1_ERR_CNT_LSB	= 0x0c8,
+	SUNI_CPPM_B1_ERR_CNT_MSB	= 0x0cc,
+	SUNI_CPPM_FRAMING_ERR_CNT_LSB	= 0x0d0,
+	SUNI_CPPM_FRAMING_ERR_CNT_MSB	= 0x0d4,
+	SUNI_CPPM_FEBE_CNT_LSB		= 0x0d8,
+	SUNI_CPPM_FEBE_CNT_MSB		= 0x0dc,
+	SUNI_CPPM_HCS_ERR_CNT_LSB	= 0x0e0,
+	SUNI_CPPM_HCS_ERR_CNT_MSB	= 0x0e4,
+	SUNI_CPPM_IDLE_UN_CELL_CNT_LSB	= 0x0e8,
+	SUNI_CPPM_IDLE_UN_CELL_CNT_MSB	= 0x0ec,
+	SUNI_CPPM_RCV_CELL_CNT_LSB	= 0x0f0,
+	SUNI_CPPM_RCV_CELL_CNT_MSB	= 0x0f4,
+	SUNI_CPPM_XMIT_CELL_CNT_LSB	= 0x0f8,
+	SUNI_CPPM_XMIT_CELL_CNT_MSB	= 0x0fc,
+	SUNI_RXCP_CTRL			= 0x100,
+	SUNI_RXCP_FCTRL			= 0x104,
+	SUNI_RXCP_INTR_EN_STS		= 0x108,
+	SUNI_RXCP_IDLE_PAT_H1		= 0x10c,
+	SUNI_RXCP_IDLE_PAT_H2		= 0x110,
+	SUNI_RXCP_IDLE_PAT_H3		= 0x114,
+	SUNI_RXCP_IDLE_PAT_H4		= 0x118,
+	SUNI_RXCP_IDLE_MASK_H1		= 0x11c,
+	SUNI_RXCP_IDLE_MASK_H2		= 0x120,
+	SUNI_RXCP_IDLE_MASK_H3		= 0x124,
+	SUNI_RXCP_IDLE_MASK_H4		= 0x128,
+	SUNI_RXCP_CELL_PAT_H1		= 0x12c,
+	SUNI_RXCP_CELL_PAT_H2		= 0x130,
+	SUNI_RXCP_CELL_PAT_H3		= 0x134,
+	SUNI_RXCP_CELL_PAT_H4		= 0x138,
+	SUNI_RXCP_CELL_MASK_H1		= 0x13c,
+	SUNI_RXCP_CELL_MASK_H2		= 0x140,
+	SUNI_RXCP_CELL_MASK_H3		= 0x144,
+	SUNI_RXCP_CELL_MASK_H4		= 0x148,
+	SUNI_RXCP_HCS_CS		= 0x14c,
+	SUNI_RXCP_LCD_CNT_THRESHOLD	= 0x150,
+	/* SUNI_RESERVED3 (0x57 - 0x54) */
+	SUNI_TXCP_CTRL			= 0x160,
+	SUNI_TXCP_INTR_EN_STS		= 0x164,
+	SUNI_TXCP_IDLE_PAT_H1		= 0x168,
+	SUNI_TXCP_IDLE_PAT_H2		= 0x16c,
+	SUNI_TXCP_IDLE_PAT_H3		= 0x170,
+	SUNI_TXCP_IDLE_PAT_H4		= 0x174,
+	SUNI_TXCP_IDLE_PAT_H5		= 0x178,
+	SUNI_TXCP_IDLE_PAYLOAD		= 0x17c,
+	SUNI_E3_FRM_FRAM_OPTIONS	= 0x180,
+	SUNI_E3_FRM_MAINT_OPTIONS	= 0x184,
+	SUNI_E3_FRM_FRAM_INTR_ENBL	= 0x188,
+	SUNI_E3_FRM_FRAM_INTR_IND_STAT	= 0x18c,
+	SUNI_E3_FRM_MAINT_INTR_ENBL	= 0x190,
+	SUNI_E3_FRM_MAINT_INTR_IND	= 0x194,
+	SUNI_E3_FRM_MAINT_STAT		= 0x198,
+	SUNI_RESERVED4			= 0x19c,
+	SUNI_E3_TRAN_FRAM_OPTIONS	= 0x1a0,
+	SUNI_E3_TRAN_STAT_DIAG_OPTIONS	= 0x1a4,
+	SUNI_E3_TRAN_BIP_8_ERR_MASK	= 0x1a8,
+	SUNI_E3_TRAN_MAINT_ADAPT_OPTS	= 0x1ac,
+	SUNI_TTB_CTRL			= 0x1b0,
+	SUNI_TTB_TRAIL_TRACE_ID_STAT	= 0x1b4,
+	SUNI_TTB_IND_ADDR		= 0x1b8,
+	SUNI_TTB_IND_DATA		= 0x1bc,
+	SUNI_TTB_EXP_PAYLOAD_TYPE	= 0x1c0,
+	SUNI_TTB_PAYLOAD_TYPE_CTRL_STAT	= 0x1c4,
+	/* SUNI_PAD5 (0x7f - 0x71) */
+	SUNI_MASTER_TEST		= 0x200,
+	/* SUNI_PAD6 (0xff - 0x80) */
+};
 
 #define SUNI_PM7345_T suni_pm7345_t
 #define SUNI_PM7345     0x20            /* Suni chip type */
-- 
1.7.6.2

^ permalink raw reply related

* [PATCH next 4/7] sc92031: use standard #defines from mii.h.
From: Francois Romieu @ 2011-09-30 10:38 UTC (permalink / raw)
  To: davem; +Cc: netdev
In-Reply-To: <20110930103604.GA26727@electric-eye.fr.zoreil.com>

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
 drivers/net/ethernet/realtek/sc92031.c |    8 +-------
 1 files changed, 1 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/realtek/sc92031.c b/drivers/net/ethernet/realtek/sc92031.c
index 128f8eb..a284d64 100644
--- a/drivers/net/ethernet/realtek/sc92031.c
+++ b/drivers/net/ethernet/realtek/sc92031.c
@@ -31,6 +31,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
+#include <linux/mii.h>
 #include <linux/crc32.h>
 
 #include <asm/irq.h>
@@ -116,16 +117,9 @@ enum  silan_registers {
    TestD8     = 0xD8,
 };
 
-#define MII_BMCR            0        // Basic mode control register
-#define MII_BMSR            1        // Basic mode status register
 #define MII_JAB             16
 #define MII_OutputStatus    24
 
-#define BMCR_FULLDPLX       0x0100    // Full duplex
-#define BMCR_ANRESTART      0x0200    // Auto negotiation restart
-#define BMCR_ANENABLE       0x1000    // Enable auto negotiation
-#define BMCR_SPEED100       0x2000    // Select 100Mbps
-#define BMSR_LSTATUS        0x0004    // Link status
 #define PHY_16_JAB_ENB      0x1000
 #define PHY_16_PORT_ENB     0x1
 
-- 
1.7.6.2

^ permalink raw reply related

* [PATCH next 5/7] rtl8150: removal of forward declarations.
From: Francois Romieu @ 2011-09-30 10:38 UTC (permalink / raw)
  To: davem; +Cc: netdev
In-Reply-To: <20110930103604.GA26727@electric-eye.fr.zoreil.com>

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
 drivers/net/usb/rtl8150.c |  111 ++++++++++++++++++++-------------------------
 1 files changed, 50 insertions(+), 61 deletions(-)

diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
index b00d692..bf8c84d 100644
--- a/drivers/net/usb/rtl8150.c
+++ b/drivers/net/usb/rtl8150.c
@@ -169,26 +169,8 @@ struct rtl8150 {
 
 typedef struct rtl8150 rtl8150_t;
 
-static void fill_skb_pool(rtl8150_t *);
-static void free_skb_pool(rtl8150_t *);
-static inline struct sk_buff *pull_skb(rtl8150_t *);
-static void rtl8150_disconnect(struct usb_interface *intf);
-static int rtl8150_probe(struct usb_interface *intf,
-			   const struct usb_device_id *id);
-static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message);
-static int rtl8150_resume(struct usb_interface *intf);
-
 static const char driver_name [] = "rtl8150";
 
-static struct usb_driver rtl8150_driver = {
-	.name =		driver_name,
-	.probe =	rtl8150_probe,
-	.disconnect =	rtl8150_disconnect,
-	.id_table =	rtl8150_table,
-	.suspend =	rtl8150_suspend,
-	.resume =	rtl8150_resume
-};
-
 /*
 **
 **	device related part of the code
@@ -333,7 +315,7 @@ static int rtl8150_set_mac_address(struct net_device *netdev, void *p)
 	/* Write the MAC address into eeprom. Eeprom writes must be word-sized,
 	   so we need to split them up. */
 	for (i = 0; i * 2 < netdev->addr_len; i++) {
-		set_registers(dev, IDR_EEPROM + (i * 2), 2, 
+		set_registers(dev, IDR_EEPROM + (i * 2), 2,
 		netdev->dev_addr + (i * 2));
 	}
 	/* Clear the WEPROM bit (preventing accidental eeprom writes). */
@@ -490,44 +472,6 @@ resched:
 	tasklet_schedule(&dev->tl);
 }
 
-static void rx_fixup(unsigned long data)
-{
-	rtl8150_t *dev;
-	struct sk_buff *skb;
-	int status;
-
-	dev = (rtl8150_t *)data;
-
-	spin_lock_irq(&dev->rx_pool_lock);
-	fill_skb_pool(dev);
-	spin_unlock_irq(&dev->rx_pool_lock);
-	if (test_bit(RX_URB_FAIL, &dev->flags))
-		if (dev->rx_skb)
-			goto try_again;
-	spin_lock_irq(&dev->rx_pool_lock);
-	skb = pull_skb(dev);
-	spin_unlock_irq(&dev->rx_pool_lock);
-	if (skb == NULL)
-		goto tlsched;
-	dev->rx_skb = skb;
-	usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
-		      dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
-try_again:
-	status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
-	if (status == -ENODEV) {
-		netif_device_detach(dev->netdev);
-	} else if (status) {
-		set_bit(RX_URB_FAIL, &dev->flags);
-		goto tlsched;
-	} else {
-		clear_bit(RX_URB_FAIL, &dev->flags);
-	}
-
-	return;
-tlsched:
-	tasklet_schedule(&dev->tl);
-}
-
 static void write_bulk_callback(struct urb *urb)
 {
 	rtl8150_t *dev;
@@ -665,6 +609,42 @@ static void free_skb_pool(rtl8150_t *dev)
 			dev_kfree_skb(dev->rx_skb_pool[i]);
 }
 
+static void rx_fixup(unsigned long data)
+{
+	struct rtl8150 *dev = (struct rtl8150 *)data;
+	struct sk_buff *skb;
+	int status;
+
+	spin_lock_irq(&dev->rx_pool_lock);
+	fill_skb_pool(dev);
+	spin_unlock_irq(&dev->rx_pool_lock);
+	if (test_bit(RX_URB_FAIL, &dev->flags))
+		if (dev->rx_skb)
+			goto try_again;
+	spin_lock_irq(&dev->rx_pool_lock);
+	skb = pull_skb(dev);
+	spin_unlock_irq(&dev->rx_pool_lock);
+	if (skb == NULL)
+		goto tlsched;
+	dev->rx_skb = skb;
+	usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
+		      dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
+try_again:
+	status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
+	if (status == -ENODEV) {
+		netif_device_detach(dev->netdev);
+	} else if (status) {
+		set_bit(RX_URB_FAIL, &dev->flags);
+		goto tlsched;
+	} else {
+		clear_bit(RX_URB_FAIL, &dev->flags);
+	}
+
+	return;
+tlsched:
+	tasklet_schedule(&dev->tl);
+}
+
 static int enable_net_traffic(rtl8150_t * dev)
 {
 	u8 cr, tcr, rcr, msr;
@@ -778,7 +758,7 @@ static int rtl8150_open(struct net_device *netdev)
 		return -ENOMEM;
 
 	set_registers(dev, IDR, 6, netdev->dev_addr);
-	
+
 	usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
 		      dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
 	if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) {
@@ -898,7 +878,7 @@ static const struct net_device_ops rtl8150_netdev_ops = {
 	.ndo_stop		= rtl8150_close,
 	.ndo_do_ioctl		= rtl8150_ioctl,
 	.ndo_start_xmit		= rtl8150_start_xmit,
-	.ndo_tx_timeout 	= rtl8150_tx_timeout,
+	.ndo_tx_timeout		= rtl8150_tx_timeout,
 	.ndo_set_rx_mode	= rtl8150_set_multicast,
 	.ndo_set_mac_address	= rtl8150_set_mac_address,
 
@@ -929,7 +909,7 @@ static int rtl8150_probe(struct usb_interface *intf,
 
 	tasklet_init(&dev->tl, rx_fixup, (unsigned long)dev);
 	spin_lock_init(&dev->rx_pool_lock);
-	
+
 	dev->udev = udev;
 	dev->netdev = netdev;
 	netdev->netdev_ops = &rtl8150_netdev_ops;
@@ -947,7 +927,7 @@ static int rtl8150_probe(struct usb_interface *intf,
 	}
 	fill_skb_pool(dev);
 	set_ethernet_addr(dev);
-	
+
 	usb_set_intfdata(intf, dev);
 	SET_NETDEV_DEV(netdev, &intf->dev);
 	if (register_netdev(netdev) != 0) {
@@ -989,6 +969,15 @@ static void rtl8150_disconnect(struct usb_interface *intf)
 	}
 }
 
+static struct usb_driver rtl8150_driver = {
+	.name		= driver_name,
+	.probe		= rtl8150_probe,
+	.disconnect	= rtl8150_disconnect,
+	.id_table	= rtl8150_table,
+	.suspend	= rtl8150_suspend,
+	.resume		= rtl8150_resume
+};
+
 static int __init usb_rtl8150_init(void)
 {
 	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
-- 
1.7.6.2

^ permalink raw reply related

* [PATCH next 6/7] drivers/net/ethernet: remove unused #define.
From: Francois Romieu @ 2011-09-30 10:38 UTC (permalink / raw)
  To: davem; +Cc: netdev
In-Reply-To: <20110930103604.GA26727@electric-eye.fr.zoreil.com>

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
 drivers/net/ethernet/amd/depca.h       |    2 --
 drivers/net/ethernet/dec/tulip/de4x5.h |    2 --
 drivers/net/ethernet/jme.h             |    1 -
 3 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/amd/depca.h b/drivers/net/ethernet/amd/depca.h
index ee42648..cdcfe42 100644
--- a/drivers/net/ethernet/amd/depca.h
+++ b/drivers/net/ethernet/amd/depca.h
@@ -157,8 +157,6 @@
 */
 #include <linux/sockios.h>
 
-#define	DEPCAIOCTL	SIOCDEVPRIVATE
-
 struct depca_ioctl {
 	unsigned short cmd;                /* Command to run */
 	unsigned short len;                /* Length of the data buffer */
diff --git a/drivers/net/ethernet/dec/tulip/de4x5.h b/drivers/net/ethernet/dec/tulip/de4x5.h
index 9f28774..ec756eb 100644
--- a/drivers/net/ethernet/dec/tulip/de4x5.h
+++ b/drivers/net/ethernet/dec/tulip/de4x5.h
@@ -991,8 +991,6 @@
 */
 #include <linux/sockios.h>
 
-#define	DE4X5IOCTL	SIOCDEVPRIVATE
-
 struct de4x5_ioctl {
 	unsigned short cmd;                /* Command to run */
 	unsigned short len;                /* Length of the data buffer */
diff --git a/drivers/net/ethernet/jme.h b/drivers/net/ethernet/jme.h
index c1f8b89..02ea27c 100644
--- a/drivers/net/ethernet/jme.h
+++ b/drivers/net/ethernet/jme.h
@@ -102,7 +102,6 @@ enum jme_spi_op_bits {
 };
 
 #define HALF_US 500	/* 500 ns */
-#define JMESPIIOCTL	SIOCDEVPRIVATE
 
 #define PCI_PRIV_PE1		0xE4
 
-- 
1.7.6.2

^ permalink raw reply related

* [PATCH next 7/7] tehuti: shorten PCI device table.
From: Francois Romieu @ 2011-09-30 10:39 UTC (permalink / raw)
  To: davem; +Cc: netdev
In-Reply-To: <20110930103604.GA26727@electric-eye.fr.zoreil.com>

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
 drivers/net/ethernet/tehuti/tehuti.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c
index 371ab7a..1151cf9 100644
--- a/drivers/net/ethernet/tehuti/tehuti.c
+++ b/drivers/net/ethernet/tehuti/tehuti.c
@@ -67,10 +67,10 @@
 #include "tehuti.h"
 
 static DEFINE_PCI_DEVICE_TABLE(bdx_pci_tbl) = {
-	{0x1FC9, 0x3009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x1FC9, 0x3010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x1FC9, 0x3014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0}
+	{ PCI_VDEVICE(TEHUTI, 0x3009), },
+	{ PCI_VDEVICE(TEHUTI, 0x3010), },
+	{ PCI_VDEVICE(TEHUTI, 0x3014), },
+	{ 0 }
 };
 
 MODULE_DEVICE_TABLE(pci, bdx_pci_tbl);
-- 
1.7.6.2

^ permalink raw reply related

* [PATCH] ipv4: NET_IPV4_ROUTE_GC_INTERVAL removal
From: Vasily Averin @ 2011-09-30 11:11 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Vasily Averin

From: Vasily Averin <vvs@sw.ru>

removing obsoleted sysctl, 
ip_rt_gc_interval variable no longer used since 2.6.38

Signed-off-by: Vasily Averin <vvs@sw.ru>
---
 include/linux/sysctl.h |    2 +-
 kernel/sysctl_binary.c |    2 +-
 net/ipv4/route.c       |    8 --------
 3 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 11684d9..9a1ec10 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -435,7 +435,7 @@ enum {
 	NET_IPV4_ROUTE_MAX_SIZE=5,
 	NET_IPV4_ROUTE_GC_MIN_INTERVAL=6,
 	NET_IPV4_ROUTE_GC_TIMEOUT=7,
-	NET_IPV4_ROUTE_GC_INTERVAL=8,
+	NET_IPV4_ROUTE_GC_INTERVAL=8, /* obsolete since 2.6.38 */
 	NET_IPV4_ROUTE_REDIRECT_LOAD=9,
 	NET_IPV4_ROUTE_REDIRECT_NUMBER=10,
 	NET_IPV4_ROUTE_REDIRECT_SILENCE=11,
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c
index e8bffbe..6318b51 100644
--- a/kernel/sysctl_binary.c
+++ b/kernel/sysctl_binary.c
@@ -214,7 +214,7 @@ static const struct bin_table bin_net_ipv4_route_table[] = {
 	{ CTL_INT,	NET_IPV4_ROUTE_GC_MIN_INTERVAL,		"gc_min_interval" },
 	{ CTL_INT,	NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS,	"gc_min_interval_ms" },
 	{ CTL_INT,	NET_IPV4_ROUTE_GC_TIMEOUT,		"gc_timeout" },
-	{ CTL_INT,	NET_IPV4_ROUTE_GC_INTERVAL,		"gc_interval" },
+	/* NET_IPV4_ROUTE_GC_INTERVAL "gc_interval" no longer used */
 	{ CTL_INT,	NET_IPV4_ROUTE_REDIRECT_LOAD,		"redirect_load" },
 	{ CTL_INT,	NET_IPV4_ROUTE_REDIRECT_NUMBER,		"redirect_number" },
 	{ CTL_INT,	NET_IPV4_ROUTE_REDIRECT_SILENCE,	"redirect_silence" },
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 075212e..f94c20d 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -120,7 +120,6 @@
 
 static int ip_rt_max_size;
 static int ip_rt_gc_timeout __read_mostly	= RT_GC_TIMEOUT;
-static int ip_rt_gc_interval __read_mostly	= 60 * HZ;
 static int ip_rt_gc_min_interval __read_mostly	= HZ / 2;
 static int ip_rt_redirect_number __read_mostly	= 9;
 static int ip_rt_redirect_load __read_mostly	= HZ / 50;
@@ -3121,13 +3120,6 @@ static ctl_table ipv4_route_table[] = {
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
-		.procname	= "gc_interval",
-		.data		= &ip_rt_gc_interval,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_jiffies,
-	},
-	{
 		.procname	= "redirect_load",
 		.data		= &ip_rt_redirect_load,
 		.maxlen		= sizeof(int),
-- 
1.7.4.1

^ permalink raw reply related

* Urgent&#8207;...
From: SENATE HOLDING (HOUSE OF SENATE) @ 2011-09-30 10:12 UTC (permalink / raw)


Attn:

You have been Issued an Atm card with code (ATM-822) Indicate When
replying to this email


KINDEST REGARDS,
MR DAVID MARK.
SENATE PRESIDENT.

^ permalink raw reply

* [PATCH net-next-2.6 1/4] be2net: Change the data type of the 'on die temperature' stat.
From: Somnath Kotur @ 2011-09-30 17:23 UTC (permalink / raw)
  To: netdev, davem; +Cc: Somnath Kotur

This was showing up as junk value on PPC /Big endian machines since
it was marked as a byte.

Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
---
 drivers/net/ethernet/emulex/benet/be.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index c5f0516..894f1a9 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -245,7 +245,7 @@ struct be_rx_obj {
 };
 
 struct be_drv_stats {
-	u8 be_on_die_temperature;
+	u32 be_on_die_temperature;
 	u32 tx_events;
 	u32 eth_red_drops;
 	u32 rx_drops_no_pbuf;
-- 
1.5.6.1

^ permalink raw reply related

* [PATCH net-next-2.6 4/4] be2net: Making die temperature ioctl call async
From: Somnath Kotur @ 2011-09-30 17:25 UTC (permalink / raw)
  To: netdev, davem; +Cc: Somnath Kotur

Also changing it's frequency to once every 64s instead of existing 32s as
it was shown to affect performance

Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
---
 drivers/net/ethernet/emulex/benet/be.h      |    5 +++
 drivers/net/ethernet/emulex/benet/be_cmds.c |   40 +++++++++++++++++----------
 2 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 894f1a9..644e8fe 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -137,6 +137,11 @@ static inline void *queue_tail_node(struct be_queue_info *q)
 	return q->dma_mem.va + q->tail * q->entry_size;
 }
 
+static inline void *queue_index_node(struct be_queue_info *q, u16 index)
+{
+	return q->dma_mem.va + index * q->entry_size;
+}
+
 static inline void queue_head_inc(struct be_queue_info *q)
 {
 	index_inc(&q->head, q->len);
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 15949b9..38c9222 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -19,7 +19,12 @@
 #include "be_cmds.h"
 
 /* Must be a power of 2 or else MODULO will BUG_ON */
-static int be_get_temp_freq = 32;
+static int be_get_temp_freq = 64;
+
+static inline void *embedded_payload(struct be_mcc_wrb *wrb)
+{
+	return wrb->payload.embedded_payload;
+}
 
 static void be_mcc_notify(struct be_adapter *adapter)
 {
@@ -85,7 +90,20 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
 			be_parse_stats(adapter);
 			adapter->stats_cmd_sent = false;
 		}
+		if (compl->tag0 ==
+				OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES) {
+			struct be_mcc_wrb *mcc_wrb =
+				queue_index_node(&adapter->mcc_obj.q,
+						compl->tag1);
+			struct be_cmd_resp_get_cntl_addnl_attribs *resp =
+				embedded_payload(mcc_wrb);
+			adapter->drv_stats.be_on_die_temperature =
+				resp->on_die_temperature;
+		}
 	} else {
+		if (compl->tag0 == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES)
+			be_get_temp_freq = 0;
+
 		if (compl_status == MCC_STATUS_NOT_SUPPORTED ||
 			compl_status == MCC_STATUS_ILLEGAL_REQUEST)
 			goto done;
@@ -404,10 +422,6 @@ int be_cmd_POST(struct be_adapter *adapter)
 	return -1;
 }
 
-static inline void *embedded_payload(struct be_mcc_wrb *wrb)
-{
-	return wrb->payload.embedded_payload;
-}
 
 static inline struct be_sge *nonembedded_sgl(struct be_mcc_wrb *wrb)
 {
@@ -1301,10 +1315,13 @@ int be_cmd_get_die_temperature(struct be_adapter *adapter)
 {
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_get_cntl_addnl_attribs *req;
+	u16 mccq_index;
 	int status;
 
 	spin_lock_bh(&adapter->mcc_lock);
 
+	mccq_index = adapter->mcc_obj.q.head;
+
 	wrb = wrb_from_mccq(adapter);
 	if (!wrb) {
 		status = -EBUSY;
@@ -1318,16 +1335,9 @@ int be_cmd_get_die_temperature(struct be_adapter *adapter)
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES, sizeof(*req));
 
-	status = be_mcc_notify_wait(adapter);
-	if (!status) {
-		struct be_cmd_resp_get_cntl_addnl_attribs *resp =
-						embedded_payload(wrb);
-		adapter->drv_stats.be_on_die_temperature =
-						resp->on_die_temperature;
-	}
-	/* If IOCTL fails once, do not bother issuing it again */
-	else
-		be_get_temp_freq = 0;
+	wrb->tag1 = mccq_index;
+
+	be_mcc_notify(adapter);
 
 err:
 	spin_unlock_bh(&adapter->mcc_lock);
-- 
1.5.6.1

^ permalink raw reply related

* [PATCH net-next-2.6 0/4] be2net: fixes
From: Somnath Kotur @ 2011-09-30 17:22 UTC (permalink / raw)
  To: netdev, davem; +Cc: Somnath Kotur

Pls apply

Somnath Kotur (4):
  be2net: Change the data type of the 'on die temperature' stat.
  be2net: Fixed Endianness issues in the response read log length field
    while retrieving FAT data
  be2net: Modified PCI MaxReadReq size to 4096 bytes
  be2net: Making die temperature ioctl call async

 drivers/net/ethernet/emulex/benet/be.h      |    7 ++++-
 drivers/net/ethernet/emulex/benet/be_cmds.c |   42 ++++++++++++++++----------
 drivers/net/ethernet/emulex/benet/be_main.c |    2 +
 3 files changed, 34 insertions(+), 17 deletions(-)

^ permalink raw reply

* [PATCH net-next-2.6 2/4] be2net: Fixed Endianness issues in the response read log length field while retrieving FAT data
From: Somnath Kotur @ 2011-09-30 17:24 UTC (permalink / raw)
  To: netdev, davem; +Cc: Somnath Kotur

This was manifesting as a crash when FAT Dump extraction was attempted on a PPC machine.

Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
---
 drivers/net/ethernet/emulex/benet/be_cmds.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 4b655b8..15949b9 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -1429,7 +1429,7 @@ void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf)
 			struct be_cmd_resp_get_fat *resp = get_fat_cmd.va;
 			memcpy(buf + offset,
 				resp->data_buffer,
-				resp->read_log_length);
+				le32_to_cpu(resp->read_log_length));
 		} else {
 			dev_err(&adapter->pdev->dev, "FAT Table Retrieve error\n");
 			goto err;
-- 
1.5.6.1

^ permalink raw reply related

* [PATCH net-next-2.6 3/4] be2net: Modified PCI MaxReadReq size to 4096 bytes
From: Somnath Kotur @ 2011-09-30 17:24 UTC (permalink / raw)
  To: netdev, davem; +Cc: Somnath Kotur


Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
---
 drivers/net/ethernet/emulex/benet/be_main.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 1a7b24c..816ce56 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2529,6 +2529,8 @@ static int be_setup(struct be_adapter *adapter)
 	adapter->link_speed = -1;
 
 	be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL);
+
+	pcie_set_readrq(adapter->pdev, 4096);
 	return 0;
 
 rx_qs_destroy:
-- 
1.5.6.1

^ permalink raw reply related

* [patch net-next-2.6] Repair wrong named definition aligned_u64
From: Jiří Župka @ 2011-09-30 12:09 UTC (permalink / raw)
  To: netdev; +Cc: loke.chetan, davem, jpirko, Jiří Župka

This repairs problem with compile library in userspace (libnl).

Signed-off-by: Jiří Župka <jzupka@redhat.com>
---
 include/linux/if_packet.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/linux/if_packet.h b/include/linux/if_packet.h
index 5e76988..f379929 100644
--- a/include/linux/if_packet.h
+++ b/include/linux/if_packet.h
@@ -173,7 +173,7 @@ struct tpacket_hdr_v1 {
 	 *    you can see which blk[s] is[are] outstanding etc.
 	 * 3. Validate kernel code.
 	 */
-	aligned_u64	seq_num;
+	__aligned_u64	seq_num;
 
 	/*
 	 * ts_last_pkt:
-- 
1.7.6.4

^ permalink raw reply related

* conntrack events over netlink flood
From: Denys Fedoryshchenko @ 2011-09-30 12:15 UTC (permalink / raw)
  To: netdev

 Hi

 After enabling events and running conntrack -E i notice flood in output 
 of server that have PPPoE and PPTP connections. Here is the output:

 OfficeNAT ~ # conntrack  -E
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
 [DESTROY] tcp      6 src=194.146.153.22 dst=194.146.153.20 sport=59986 
 dport=22 src=194.146.153.20 dst=194.146.153.22 sport=22 dport=59986 
 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]
  [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
 srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
 dstkey=0x0 [ASSURED]

 Inside VPN there is nothing abnormal:
 OfficeNAT ~ # tcpdump -ni eth1 host 192.168.0.140
 tcpdump: verbose output suppressed, use -v or -vv for full protocol 
 decode
 listening on eth1, link-type EN10MB (Ethernet), capture size 65535 
 bytes
 15:14:25.197228 IP 192.168.0.1 > 192.168.0.140: GREv1, call 0, seq 
 36871343, ack 23926537, length 286: IP 10.190.197.4.8291 > 
 10.0.0.11.34297: Flags [P.], seq 2294356048:2294356262, ack 1493604004, 
 win 7176, options [nop,nop,TS val 156039405 ecr 70523361], length 214
 15:14:25.197720 IP 192.168.0.140 > 192.168.0.1: GREv1, call 3, seq 
 23926538, ack 36871342, length 84: IP 10.0.0.11 > 80.83.21.25: ICMP echo 
 request, id 47921, seq 62122, length 44
 15:14:25.208438 IP 192.168.0.140 > 192.168.0.1: GREv1, call 3, seq 
 23926539, ack 36871343, length 72: IP 10.0.0.11.34297 > 
 10.190.197.4.8291: Flags [.], ack 214, win 502, options [nop,nop,TS val 
 70523364 ecr 156039405], length 0
 15:14:25.208455 IP 192.168.0.140 > 192.168.0.1: GREv1, call 3, seq 
 23926540, length 80: IP 10.0.0.11 > 80.83.21.27: ICMP echo request, id 
 64042, seq 29149, length 44
 15:14:25.208488 IP 192.168.0.140 > 192.168.0.1: GREv1, call 3, seq 
 23926541, length 140: IP 10.0.0.11.59486 > 10.55.23.1.8291: Flags [P.], 
 seq 3129587623:3129587695, ack 1529616820, win 964, options [nop,nop,TS 
 val 70523364 ecr 1211500666], length 72
 15:14:25.218655 IP 192.168.0.1 > 192.168.0.140: GREv1, call 0, seq 
 36871344, ack 23926541, length 112: IP 10.25.65.3 > 10.0.0.11: ICMP time 
 exceeded in-transit, length 72
 15:14:25.219092 IP 192.168.0.140 > 192.168.0.1: GREv1, call 3, seq 
 23926542, length 68: IP 10.0.0.11.41472 > 10.190.199.4.8291: Flags [.], 
 ack 937942646, win 502, options [nop,nop,TS val 70523366 ecr 510725509], 
 length 0
 15:14:25.228513 IP 192.168.0.140 > 192.168.0.1: GREv1, call 3, seq 
 23926543, ack 36871344, length 84: IP 10.0.0.11 > 194.146.152.54: ICMP 
 echo request, id 45864, seq 24534, length 44
 15:14:25.228524 IP 192.168.0.140 > 192.168.0.1: GREv1, call 3, seq 
 23926544, length 80: IP 10.0.0.11 > 194.146.152.54: ICMP echo request, 
 id 24373, seq 15283, length 44
 15:14:25.228601 IP 192.168.0.140 > 192.168.0.1: GREv1, call 3, seq 
 23926545, length 234: IP 10.0.0.11.49437 > 192.168.20.55.8291: Flags 
 [P.], seq 2487750543:2487750709, ack 830585230, win 819, options 
 [nop,nop,TS val 70523366 ecr 1211500747], length 166
 15:14:25.233437 IP 192.168.0.1 > 192.168.0.140: GREv1, call 0, seq 
 36871345, ack 23926545, length 141: IP 192.168.20.55.8291 > 
 10.0.0.11.49437: Flags [P.], seq 1:70, ack 166, win 11700, options 
 [nop,nop,TS val 1211500757 ecr 70523366], length 69
 15:14:25.235266 IP 192.168.0.1 > 192.168.0.140: GREv1, call 0, seq 
 36871346, length 173: IP 10.190.199.4.8291 > 10.0.0.11.41472: Flags 
 [P.], seq 1:106, ack 0, win 8424, options [nop,nop,TS val 510725517 ecr 
 70523366], length 105
 15:14:25.235778 IP 192.168.0.140 > 192.168.0.1: GREv1, call 3, ack 
 36871346, no-payload, length 12
 15:14:25.236650 IP 192.168.0.1 > 192.168.0.140: GREv1, call 0, seq 
 36871347, length 1316: IP 10.55.23.1.8291 > 10.0.0.11.59486: Flags [.], 
 seq 1:1249, ack 72, win 6084, options [nop,nop,TS val 1211500758 ecr 
 70523364], length 1248
 15:14:25.236842 IP 192.168.0.1 > 192.168.0.140: GREv1, call 0, seq 
 36871348, length 1316: IP 10.55.23.1.8291 > 10.0.0.11.59486: Flags [.], 
 seq 1249:2497, ack 72, win 6084, options [nop,nop,TS val 1211500758 ecr 
 70523364], length 1248
 15:14:25.236963 IP 192.168.0.1 > 192.168.0.140: GREv1, call 0, seq 
 36871349, length 1316: IP 10.55.23.1.8291 > 10.0.0.11.59486: Flags [.], 
 seq 2497:3745, ack 72, win 6084, options [nop,nop,TS val 1211500758 ecr 
 70523364], length 1248
 15:14:25.237455 IP 192.168.0.140 > 192.168.0.1: GREv1, call 3, seq 
 23926546, length 229: IP 10.0.0.11.41472 > 10.190.199.4.8291: Flags 
 [P.], seq 0:161, ack 1, win 502, options [nop,nop,TS val 70523367 ecr 
 510725509], length 161
 15:14:25.237786 IP 192.168.0.140 > 192.168.0.1: GREv1, call 3, ack 
 36871349, no-payload, length 12

 Is it considered as a bug? I think it should not send on each packet 
 conntrack event.

 ---
 System administrator
 Denys Fedoryshchenko
 Virtual ISP S.A.L.

^ permalink raw reply

* [RFC patch net-next-2.6] net: introduce ethernet teaming device
From: Jiri Pirko @ 2011-09-30 12:44 UTC (permalink / raw)
  To: netdev
  Cc: davem, eric.dumazet, bhutchings, shemminger, fubar, andy, tgraf,
	ebiederm, mirqus, kaber, greearb

This patch introduces new network device called team. It supposes to be
very fast, simple, userspace-driven parallel to existing bonding device.
Userspace library called libteam with couple of demo apps is available
here:
https://github.com/jpirko/libteam
Note it's still in its dipers atm.

team<->libteam use generic netlink for communication. That and rtnl
suppose to be the only way to configure team device, no sysfs etc.

In near future python binding for libteam will be introduced. Also
daemon providing arpmon/miimon active-backup functionality will
be introduced. All what's necessary is already implemented in kernel team
driver.

Plan is to support 8023ad in near future with it's logic mainly in
userspace daemon as well.

Please review, try, comment. All feedback would be much appreciated.

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
 MAINTAINERS             |    7 +
 drivers/net/Kconfig     |   15 +
 drivers/net/Makefile    |    1 +
 drivers/net/team.c      | 1783 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/Kbuild    |    1 +
 include/linux/if.h      |    1 +
 include/linux/if_team.h |  126 ++++
 7 files changed, 1934 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/team.c
 create mode 100644 include/linux/if_team.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 5faf685..17ad107 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6372,6 +6372,13 @@ W:	http://tcp-lp-mod.sourceforge.net/
 S:	Maintained
 F:	net/ipv4/tcp_lp.c
 
+TEAM DRIVER
+M:	Jiri Pirko <jpirko@redhat.com>
+L:	netdev@vger.kernel.org
+S:	Supported
+F:	drivers/net/team.c
+F:	include/linux/team.h
+
 TEGRA SUPPORT
 M:	Colin Cross <ccross@android.com>
 M:	Erik Gilling <konkers@android.com>
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 583f66c..0d74e9d 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -125,6 +125,21 @@ config IFB
 	  'ifb1' etc.
 	  Look at the iproute2 documentation directory for usage etc
 
+config NET_TEAM
+	tristate "Ethernet teaming support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	---help---
+	  This allows one to create virtual interfaces that teams together
+	  multiple ethernet devices.
+
+	  Team devices can be added using the "ip" command from the
+	  iproute2 package:
+
+	  "ip link add link [ address MAC ] [ NAME ] type team"
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called team.
+
 config MACVLAN
 	tristate "MAC-VLAN support (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index fa877cd..e3d3e81 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_NET) += Space.o loopback.o
 obj-$(CONFIG_NETCONSOLE) += netconsole.o
 obj-$(CONFIG_PHYLIB) += phy/
 obj-$(CONFIG_RIONET) += rionet.o
+obj-$(CONFIG_NET_TEAM) += team.o
 obj-$(CONFIG_TUN) += tun.o
 obj-$(CONFIG_VETH) += veth.o
 obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
diff --git a/drivers/net/team.c b/drivers/net/team.c
new file mode 100644
index 0000000..3641d51
--- /dev/null
+++ b/drivers/net/team.c
@@ -0,0 +1,1783 @@
+/*
+ * net/drivers/team.c - Network team device driver
+ * Copyright (c) 2011 Jiri Pirko <jpirko@redhat.com>
+ *
+ * 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 Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/rcupdate.h>
+#include <linux/errno.h>
+#include <linux/notifier.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/socket.h>
+#include <linux/etherdevice.h>
+#include <linux/rtnetlink.h>
+#include <net/rtnetlink.h>
+#include <net/genetlink.h>
+#include <net/netlink.h>
+#include <linux/if_team.h>
+
+#define DRV_NAME "team"
+
+
+/*************************************
+ * Structures and helpers definitions
+ *************************************/
+
+struct team;
+
+struct team_port {
+	struct net_device *dev;
+	struct hlist_node hlist; /* node in hash list */
+	struct list_head list; /* node in ordinary list */
+	struct team *team;
+	int index;
+
+	/*
+	 * A place for storing original values of the device before it
+	 * become a port.
+	 */
+	struct {
+		unsigned char dev_addr[MAX_ADDR_LEN];
+		unsigned int mtu;
+	} orig;
+
+	bool linkup;
+	u32 speed;
+	u8 duplex;
+
+	struct rcu_head rcu;
+};
+
+struct team_mode_ops {
+	int (*init)(struct team *team);
+	void (*exit)(struct team *team);
+	rx_handler_result_t (*receive)(struct team *team,
+				       struct team_port *port,
+				       struct sk_buff *skb);
+	bool (*transmit)(struct team *team, struct sk_buff *skb);
+	int (*port_enter)(struct team *team, struct team_port *port);
+	void (*port_leave)(struct team *team, struct team_port *port);
+	void (*port_change_mac)(struct team *team, struct team_port *port);
+};
+
+enum team_option_type {
+	TEAM_OPTION_TYPE_U32,
+	TEAM_OPTION_TYPE_STRING,
+};
+
+struct team_option {
+	struct list_head list;
+	const char *name;
+	enum team_option_type type;
+	int (*getter)(struct team *team, void *arg);
+	int (*setter)(struct team *team, void *arg);
+};
+
+struct team_mode {
+	const char *kind;
+	const struct team_mode_ops *ops;
+};
+
+struct rr_priv {
+	unsigned int sent_packets;
+};
+
+struct ab_priv {
+	struct team_port __rcu *active_port;
+};
+
+struct team {
+	struct net_device *dev; /* associated netdevice */
+	spinlock_t lock; /* used for overall locking, e.g. port lists write */
+
+	/*
+	 * port lists with port count
+	 */
+	int port_count;
+	struct hlist_head *port_hlist;
+	struct list_head port_list;
+
+	struct list_head option_list;
+
+	const char *mode_kind;
+	struct team_mode_ops mode_ops;
+	union {
+		char priv_first_byte;
+		struct ab_priv ab_priv;
+		struct rr_priv rr_priv;
+	};
+};
+
+#define TEAM_PORT_HASHBITS 4
+#define TEAM_PORT_HASHENTRIES (1 << TEAM_PORT_HASHBITS)
+
+static struct hlist_head *team_port_index_hash(const struct team *team,
+					       int port_index)
+{
+	return &team->port_hlist[port_index & (TEAM_PORT_HASHENTRIES - 1)];
+}
+
+static struct team_port *team_get_port_by_index_rcu(const struct team *team,
+						    int port_index)
+{
+	struct hlist_node *p;
+	struct team_port *port;
+	struct hlist_head *head = team_port_index_hash(team, port_index);
+
+	hlist_for_each_entry_rcu(port, p, head, hlist)
+		if (port->index == port_index)
+			return port;
+	return NULL;
+}
+
+static bool team_port_find(const struct team *team,
+			   const struct team_port *port)
+{
+	struct team_port *cur;
+
+	list_for_each_entry(cur, &team->port_list, list)
+		if (cur == port)
+			return true;
+	return false;
+}
+
+#define team_port_exists(dev) (dev->priv_flags & IFF_TEAM_PORT)
+
+static struct team_port *team_port_get_rcu(const struct net_device *dev)
+{
+	struct team_port *port = rcu_dereference(dev->rx_handler_data);
+
+	return team_port_exists(dev) ? port : NULL;
+}
+
+static struct team_port *team_port_get_rtnl(const struct net_device *dev)
+{
+	struct team_port *port = rtnl_dereference(dev->rx_handler_data);
+
+	return team_port_exists(dev) ? port : NULL;
+}
+
+/*
+ * Since the ability to change mac address for open port device is tested in
+ * team_port_add, this function can be called without control of return value
+ */
+static int __set_port_mac(struct net_device *port_dev,
+			  const unsigned char *dev_addr)
+{
+	struct sockaddr addr;
+
+	memcpy(addr.sa_data, dev_addr, ETH_ALEN);
+	addr.sa_family = ARPHRD_ETHER;
+	return dev_set_mac_address(port_dev, &addr);
+}
+
+static int team_port_set_orig_mac(struct team_port *port)
+{
+	return __set_port_mac(port->dev, port->orig.dev_addr);
+}
+
+static int team_port_set_team_mac(struct team_port *port)
+{
+	return __set_port_mac(port->dev, port->team->dev->dev_addr);
+}
+
+
+/*******************
+ * Options handling
+ *******************/
+
+static void team_options_register(struct team *team,
+				  struct team_option *option,
+				  size_t option_count)
+{
+	int i;
+
+	for (i = 0; i < option_count; i++, option++)
+		list_add_tail(&option->list, &team->option_list);
+}
+
+static void __team_options_change_check(struct team *team,
+					struct team_option *changed_option);
+
+static void __team_options_unregister(struct team *team,
+				      struct team_option *option,
+				      size_t option_count)
+{
+	int i;
+
+	for (i = 0; i < option_count; i++, option++)
+		list_del(&option->list);
+}
+
+static void team_options_unregister(struct team *team,
+				    struct team_option *option,
+				    size_t option_count)
+{
+	__team_options_unregister(team, option, option_count);
+	__team_options_change_check(team, NULL);
+}
+
+static int team_option_get(struct team *team, struct team_option *option,
+			   void *arg)
+{
+	return option->getter(team, arg);
+}
+
+static int team_option_set(struct team *team, struct team_option *option,
+			   void *arg)
+{
+	int err;
+
+	err = option->setter(team, arg);
+	if (err)
+		return err;
+
+	__team_options_change_check(team, option);
+	return err;
+}
+
+/******************************
+ * Round-robin mode definition
+ ******************************/
+
+static struct team_port *__get_first_port_up(struct team *team,
+					     struct team_port *port)
+{
+	struct team_port *cur;
+
+	if (port->linkup)
+		return port;
+	cur = port;
+	list_for_each_entry_continue_rcu(cur, &team->port_list, list)
+		if (cur->linkup)
+			return cur;
+	list_for_each_entry_rcu(cur, &team->port_list, list) {
+		if (cur == port)
+			break;
+		if (cur->linkup)
+			return cur;
+	}
+	return NULL;
+}
+
+static bool rr_transmit(struct team *team, struct sk_buff *skb)
+{
+	struct team_port *port;
+	int port_index;
+
+	port_index = team->rr_priv.sent_packets++ % team->port_count;
+	port = team_get_port_by_index_rcu(team, port_index);
+	port = __get_first_port_up(team, port);
+	if (unlikely(!port))
+		goto drop;
+	skb->dev = port->dev;
+	if (dev_queue_xmit(skb))
+		goto drop;
+
+	return true;
+
+drop:
+	dev_kfree_skb(skb);
+	return false;
+}
+
+static int rr_port_enter(struct team *team, struct team_port *port)
+{
+	return team_port_set_team_mac(port);
+}
+
+static void rr_port_change_mac(struct team *team, struct team_port *port)
+{
+	team_port_set_team_mac(port);
+}
+
+static const struct team_mode_ops rr_mode_ops = {
+	.transmit		= rr_transmit,
+	.port_enter		= rr_port_enter,
+	.port_change_mac	= rr_port_change_mac,
+};
+
+static const struct team_mode rr_mode = {
+	.kind		= "roundrobin",
+	.ops		= &rr_mode_ops,
+};
+
+
+/********************************
+ * Active-backup mode definition
+ ********************************/
+
+static rx_handler_result_t ab_receive(struct team *team, struct team_port *port,
+				      struct sk_buff *skb) {
+	struct team_port *active_port;
+
+	active_port = rcu_dereference(team->ab_priv.active_port);
+	if (active_port != port)
+		return RX_HANDLER_EXACT;
+	return RX_HANDLER_ANOTHER;
+}
+
+static bool ab_transmit(struct team *team, struct sk_buff *skb)
+{
+	struct team_port *active_port;
+
+	active_port = rcu_dereference(team->ab_priv.active_port);
+	if (unlikely(!active_port))
+		goto drop;
+	skb->dev = active_port->dev;
+	if (dev_queue_xmit(skb))
+		goto drop;
+	return true;
+
+drop:
+	dev_kfree_skb(skb);
+	return false;
+}
+
+static void ab_port_leave(struct team *team, struct team_port *port)
+{
+	if (team->ab_priv.active_port == port)
+		rcu_assign_pointer(team->ab_priv.active_port, NULL);
+}
+
+static void ab_port_change_mac(struct team *team, struct team_port *port)
+{
+	if (team->ab_priv.active_port == port)
+		team_port_set_team_mac(port);
+}
+
+static int ab_active_port_get(struct team *team, void *arg)
+{
+	u32 *ifindex = arg;
+
+	*ifindex = 0;
+	if (team->ab_priv.active_port)
+		*ifindex = team->ab_priv.active_port->dev->ifindex;
+	return 0;
+}
+
+static int ab_active_port_set(struct team *team, void *arg)
+{
+	u32 *ifindex = arg;
+	struct team_port *port;
+
+	list_for_each_entry_rcu(port, &team->port_list, list) {
+		if (port->dev->ifindex == *ifindex) {
+			struct team_port *ac_port = team->ab_priv.active_port;
+
+			/* rtnl_lock needs to be held when setting macs */
+			rtnl_lock();
+			if (ac_port)
+				team_port_set_orig_mac(ac_port);
+			rcu_assign_pointer(team->ab_priv.active_port, port);
+			team_port_set_team_mac(port);
+			rtnl_unlock();
+			return 0;
+		}
+	}
+	return -ENOENT;
+}
+
+static struct team_option ab_options[] = {
+	{
+		.name = "activeport",
+		.type = TEAM_OPTION_TYPE_U32,
+		.getter = ab_active_port_get,
+		.setter = ab_active_port_set,
+	},
+};
+
+int ab_init(struct team *team)
+{
+	team_options_register(team, ab_options, ARRAY_SIZE(ab_options));
+	return 0;
+}
+
+void ab_exit(struct team *team)
+{
+	team_options_unregister(team, ab_options, ARRAY_SIZE(ab_options));
+}
+
+static const struct team_mode_ops ab_mode_ops = {
+	.init			= ab_init,
+	.exit			= ab_exit,
+	.receive		= ab_receive,
+	.transmit		= ab_transmit,
+	.port_leave		= ab_port_leave,
+	.port_change_mac	= ab_port_change_mac,
+};
+
+static const struct team_mode ab_mode = {
+	.kind		= "activebackup",
+	.ops		= &ab_mode_ops,
+};
+
+
+/****************
+ * Mode handling
+ ****************/
+
+static const struct team_mode *team_modes[] = {
+	&rr_mode,
+	&ab_mode,
+};
+
+static const int team_mode_count = ARRAY_SIZE(team_modes);
+
+static int team_find_mode(const char *kind)
+{
+	int i;
+
+	for (i = 0; i < team_mode_count; i++) {
+		const struct team_mode *mode = team_modes[i];
+
+		if (strcmp(mode->kind, kind) == 0)
+			return i;
+	}
+	return -ENOENT;
+}
+
+/*
+ * We can benefit from the fact that it's ensured no port is present
+ * at the time of mode change.
+ */
+static void __team_change_mode(struct team *team, const int mode_index)
+{
+	const struct team_mode *mode = team_modes[mode_index];
+
+	if (team->mode_ops.exit)
+		team->mode_ops.exit(team);
+
+	if (mode_index < 0)
+		return;
+
+	memcpy(&team->mode_ops, mode->ops, sizeof(struct team_mode_ops));
+
+	/* zero private data area */
+	memset(&team->priv_first_byte, 0,
+	       sizeof(struct team) - offsetof(struct team, priv_first_byte));
+
+	team->mode_kind = mode->kind;
+	if (team->mode_ops.init)
+		team->mode_ops.init(team);
+
+	return;
+}
+
+static int team_change_mode(struct team *team, const char *kind)
+{
+	int mode_index;
+	struct net_device *dev = team->dev;
+
+	if (!list_empty(&team->port_list)) {
+		netdev_err(dev, "No ports can be present during "
+				"mode change\n");
+		return -EBUSY;
+	}
+
+	if (strcmp(team->mode_kind, kind) == 0) {
+		netdev_err(dev, "Unable to change to the same mode "
+				"the team is in\n");
+		return -EINVAL;
+	}
+
+	mode_index = team_find_mode(kind);
+	if (mode_index < 0) {
+		netdev_err(dev, "Mode \"%s\" is not loaded\n", kind);
+		return -EINVAL;
+	}
+
+	__team_change_mode(team, mode_index);
+
+	netdev_info(dev, "Mode changed to \"%s\"\n", kind);
+	return 0;
+}
+
+
+/************************
+ * Rx path frame handler
+ ************************/
+
+/* note: already called with rcu_read_lock */
+static rx_handler_result_t team_handle_frame(struct sk_buff **pskb)
+{
+	struct sk_buff *skb = *pskb;
+	struct team_port *port;
+	struct team *team;
+	rx_handler_result_t res = RX_HANDLER_ANOTHER;
+
+	skb = skb_share_check(skb, GFP_ATOMIC);
+	if (!skb)
+		return RX_HANDLER_CONSUMED;
+
+	*pskb = skb;
+
+	port = team_port_get_rcu(skb->dev);
+	team = port->team;
+
+	if (team->mode_ops.receive)
+		 res = team->mode_ops.receive(team, port, skb);
+
+	if (res == RX_HANDLER_ANOTHER)
+		skb->dev = team->dev;
+
+	return res;
+}
+
+
+/****************
+ * Port handling
+ ****************/
+
+static int team_port_list_init(struct team *team)
+{
+	int i;
+	struct hlist_head *hash;
+
+	hash = kmalloc(sizeof(*hash) * TEAM_PORT_HASHENTRIES, GFP_KERNEL);
+	if (hash != NULL) {
+		for (i = 0; i < TEAM_PORT_HASHENTRIES; i++)
+			INIT_HLIST_HEAD(&hash[i]);
+	} else {
+		return -ENOMEM;
+	}
+	team->port_hlist = hash;
+	INIT_LIST_HEAD(&team->port_list);
+	return 0;
+}
+
+static void team_port_list_fini(struct team *team)
+{
+	kfree(team->port_hlist);
+}
+
+/*
+ * Add/delete port to the team port list. Write guarded by rtnl_lock.
+ * Takes care of correct port->index setup (might be racy).
+ */
+static void team_port_list_add_port(struct team *team,
+				    struct team_port *port)
+{
+	port->index = team->port_count++;
+	hlist_add_head_rcu(&port->hlist,
+			   team_port_index_hash(team, port->index));
+	list_add_tail_rcu(&port->list, &team->port_list);
+}
+
+static void __reconstruct_port_hlist(struct team *team, int rm_index)
+{
+	int i;
+	struct team_port *port;
+
+	for (i = rm_index + 1; i < team->port_count; i++) {
+		port = team_get_port_by_index_rcu(team, i);
+		hlist_del_rcu(&port->hlist);
+		port->index--;
+		hlist_add_head_rcu(&port->hlist,
+				   team_port_index_hash(team, port->index));
+	}
+}
+
+static void team_port_list_del_port(struct team *team,
+				   struct team_port *port)
+{
+	int rm_index = port->index;
+
+	hlist_del_rcu(&port->hlist);
+	list_del_rcu(&port->list);
+	__reconstruct_port_hlist(team, rm_index);
+	team->port_count--;
+}
+
+static int team_port_enter(struct team *team, struct team_port *port)
+{
+	int err = 0;
+
+	dev_hold(team->dev);
+	port->dev->priv_flags |= IFF_TEAM_PORT;
+	if (team->mode_ops.port_enter) {
+		err = team->mode_ops.port_enter(team, port);
+		if (err)
+			netdev_err(team->dev, "Device %s failed to "
+					      "enter team mode\n",
+				   port->dev->name);
+	}
+	return err;
+}
+
+static void team_port_leave(struct team *team, struct team_port *port)
+{
+	if (team->mode_ops.port_leave)
+		team->mode_ops.port_leave(team, port);
+	port->dev->priv_flags &= ~IFF_TEAM_PORT;
+	dev_put(team->dev);
+}
+
+static void __team_port_change_check(struct team_port *port, bool linkup);
+
+static int team_port_add(struct team *team, struct net_device *port_dev)
+{
+	struct net_device *dev = team->dev;
+	struct team_port *port;
+	char *portname = port_dev->name;
+	char tmp_addr[ETH_ALEN];
+	int err;
+
+	if (port_dev->flags & IFF_LOOPBACK ||
+	    port_dev->type != ARPHRD_ETHER) {
+		netdev_err(dev, "Device %s is of an unsupported type\n",
+			   portname);
+		return -EINVAL;
+	}
+
+	if (team_port_exists(port_dev)) {
+		netdev_err(dev, "Device %s is already a port "
+				"of a team device\n", portname);
+		return -EBUSY;
+	}
+
+	if (port_dev->flags & IFF_UP) {
+		netdev_err(dev, "Device %s is up. Set it down before "
+				"adding it as a team port\n", portname);
+		return -EBUSY;
+	}
+
+	port = kzalloc(sizeof(struct team_port), GFP_KERNEL);
+	if (!port)
+		return -ENOMEM;
+
+	port->dev = port_dev;
+	port->team = team;
+
+	port->orig.mtu = port_dev->mtu;
+	err = dev_set_mtu(port_dev, dev->mtu);
+	if (err) {
+		netdev_dbg(dev, "Error %d calling dev_set_mtu\n", err);
+		goto err_set_mtu;
+	}
+
+	memcpy(port->orig.dev_addr, port_dev->dev_addr, ETH_ALEN);
+	random_ether_addr(tmp_addr);
+	err = __set_port_mac(port_dev, tmp_addr);
+	if (err) {
+		netdev_dbg(dev, "Device %s mac addr set failed\n",
+			   portname);
+		goto err_set_mac_rand;
+	}
+
+	err = dev_open(port_dev);
+	if (err) {
+		netdev_dbg(dev, "Device %s opening failed\n",
+			   portname);
+		goto err_dev_open;
+	}
+
+	err = team_port_set_orig_mac(port);
+	if (err) {
+		netdev_dbg(dev, "Device %s mac addr set failed - Device does "
+				"not support addr change when it's opened\n",
+			   portname);
+		goto err_set_mac_opened;
+	}
+
+	err = team_port_enter(team, port);
+	if (err) {
+		netdev_err(dev, "Device %s failed to enter team mode\n",
+			   portname);
+		goto err_port_enter;
+	}
+
+	err = netdev_set_master(port_dev, dev);
+	if (err) {
+		netdev_err(dev, "Device %s failed to set "
+				"master\n", portname);
+		goto err_set_master;
+	}
+
+	err = netdev_rx_handler_register(port_dev, team_handle_frame,
+					 port);
+	if (err) {
+		netdev_err(dev, "Device %s failed to register "
+				"rx_handler\n", portname);
+		goto err_handler_register;
+	}
+
+	team_port_list_add_port(team, port);
+
+	__team_port_change_check(port, !!netif_carrier_ok(port_dev));
+
+	netdev_info(dev, "Port device %s added\n", portname);
+
+	return 0;
+
+err_handler_register:
+	netdev_set_master(port_dev, NULL);
+
+err_set_master:
+	team_port_leave(team, port);
+
+err_port_enter:
+err_set_mac_opened:
+	dev_close(port_dev);
+
+err_dev_open:
+	team_port_set_orig_mac(port);
+
+err_set_mac_rand:
+	dev_set_mtu(port_dev, port->orig.mtu);
+
+err_set_mtu:
+	kfree(port);
+
+	return err;
+}
+
+static int team_port_del(struct team *team, struct net_device *port_dev)
+{
+	struct net_device *dev = team->dev;
+	struct team_port *port;
+	char *portname = port_dev->name;
+
+	port = team_port_get_rtnl(port_dev);
+	if (!port || !team_port_find(team, port)) {
+		netdev_err(dev, "Device %s does not act as a port "
+				"of this team\n", portname);
+		return -ENOENT;
+	}
+
+	__team_port_change_check(port, false);
+	team_port_list_del_port(team, port);
+	netdev_rx_handler_unregister(port_dev);
+	netdev_set_master(port_dev, NULL);
+	team_port_leave(team, port);
+	dev_close(port_dev);
+	team_port_set_orig_mac(port);
+	dev_set_mtu(port_dev, port->orig.mtu);
+	synchronize_rcu();
+	kfree(port);
+	netdev_info(dev, "Port device %s removed\n", portname);
+
+	return 0;
+}
+
+
+/*****************
+ * Net device ops
+ ****************/
+
+static int team_mode_option_get(struct team *team, void *arg)
+{
+	const char **str = arg;
+
+	*str = team->mode_kind;
+	return 0;
+}
+
+static int team_mode_option_set(struct team *team, void *arg)
+{
+	const char **str = arg;
+
+	return team_change_mode(team, *str);
+}
+
+static struct team_option team_options[] = {
+	{
+		.name = "mode",
+		.type = TEAM_OPTION_TYPE_STRING,
+		.getter = team_mode_option_get,
+		.setter = team_mode_option_set,
+	},
+};
+
+static int team_init(struct net_device *dev)
+{
+	struct team *team = netdev_priv(dev);
+	int err;
+
+	team->dev = dev;
+	spin_lock_init(&team->lock);
+
+	err = team_port_list_init(team);
+	if (err)
+		return err;
+
+	INIT_LIST_HEAD(&team->option_list);
+	team_options_register(team, team_options, ARRAY_SIZE(team_options));
+	__team_change_mode(team, 0); /* set default mode */
+	netif_carrier_off(dev);
+
+	return 0;
+}
+
+static void team_uninit(struct net_device *dev)
+{
+	struct team *team = netdev_priv(dev);
+	struct team_port *port;
+	struct team_port *tmp;
+
+	spin_lock(&team->lock);
+	list_for_each_entry_safe(port, tmp, &team->port_list, list)
+		team_port_del(team, port->dev);
+
+	__team_change_mode(team, -1); /* cleanup */
+	__team_options_unregister(team, team_options, ARRAY_SIZE(team_options));
+	spin_unlock(&team->lock);
+}
+
+static void team_destructor(struct net_device *dev)
+{
+	struct team *team = netdev_priv(dev);
+
+	team_port_list_fini(team);
+	free_netdev(dev);
+}
+
+static int team_open(struct net_device *dev)
+{
+	netif_carrier_on(dev);
+	return 0;
+}
+
+static int team_close(struct net_device *dev)
+{
+	netif_carrier_off(dev);
+	return 0;
+}
+
+/*
+ * note: already called with rcu_read_lock
+ */
+static netdev_tx_t team_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct team *team = netdev_priv(dev);
+
+	/*
+	 * Ensure transmit function is called only in case there is at least
+	 * one port present.
+	 */
+	if (likely(!list_empty(&team->port_list)))
+		team->mode_ops.transmit(team, skb);
+
+	return NETDEV_TX_OK;
+}
+
+static void team_change_rx_flags(struct net_device *dev, int change)
+{
+	struct team *team = netdev_priv(dev);
+	struct team_port *port;
+	int inc;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(port, &team->port_list, list) {
+		if (change & IFF_PROMISC) {
+			inc = dev->flags & IFF_PROMISC ? 1 : -1;
+			dev_set_promiscuity(port->dev, inc);
+		}
+		if (change & IFF_ALLMULTI) {
+			inc = dev->flags & IFF_ALLMULTI ? 1 : -1;
+			dev_set_allmulti(port->dev, inc);
+		}
+	}
+	rcu_read_unlock();
+}
+
+static void team_set_rx_mode(struct net_device *dev)
+{
+	struct team *team = netdev_priv(dev);
+	struct team_port *port;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(port, &team->port_list, list) {
+		dev_uc_sync(port->dev, dev);
+		dev_mc_sync(port->dev, dev);
+	}
+	rcu_read_unlock();
+}
+
+static int team_set_mac_address(struct net_device *dev, void *p)
+{
+	struct team *team = netdev_priv(dev);
+	struct team_port *port;
+	struct sockaddr *addr = p;
+
+	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+	rcu_read_lock();
+	list_for_each_entry_rcu(port, &team->port_list, list)
+		if (team->mode_ops.port_change_mac)
+			team->mode_ops.port_change_mac(team, port);
+	rcu_read_unlock();
+	return 0;
+}
+
+static int team_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct team *team = netdev_priv(dev);
+	struct team_port *port;
+	int err;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(port, &team->port_list, list) {
+		err = dev_set_mtu(port->dev, new_mtu);
+		if (err) {
+			netdev_err(dev, "Device %s failed to change mtu",
+				   port->dev->name);
+			goto unwind;
+		}
+	}
+	rcu_read_unlock();
+
+	dev->mtu = new_mtu;
+
+	return 0;
+
+unwind:
+	list_for_each_entry_continue_reverse(port, &team->port_list, list)
+		dev_set_mtu(port->dev, dev->mtu);
+
+	rcu_read_unlock();
+	return err;
+}
+
+static struct rtnl_link_stats64 *team_get_stats(struct net_device *dev,
+						struct rtnl_link_stats64 *stats)
+{
+	struct team *team = netdev_priv(dev);
+	struct rtnl_link_stats64 temp;
+	struct team_port *port;
+
+	memset(stats, 0, sizeof(*stats));
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(port, &team->port_list, list) {
+		const struct rtnl_link_stats64 *pstats;
+
+		pstats = dev_get_stats(port->dev, &temp);
+
+		stats->rx_packets += pstats->rx_packets;
+		stats->rx_bytes += pstats->rx_bytes;
+		stats->rx_errors += pstats->rx_errors;
+		stats->rx_dropped += pstats->rx_dropped;
+
+		stats->tx_packets += pstats->tx_packets;
+		stats->tx_bytes += pstats->tx_bytes;
+		stats->tx_errors += pstats->tx_errors;
+		stats->tx_dropped += pstats->tx_dropped;
+
+		stats->multicast += pstats->multicast;
+		stats->collisions += pstats->collisions;
+
+		stats->rx_length_errors += pstats->rx_length_errors;
+		stats->rx_over_errors += pstats->rx_over_errors;
+		stats->rx_crc_errors += pstats->rx_crc_errors;
+		stats->rx_frame_errors += pstats->rx_frame_errors;
+		stats->rx_fifo_errors += pstats->rx_fifo_errors;
+		stats->rx_missed_errors += pstats->rx_missed_errors;
+
+		stats->tx_aborted_errors += pstats->tx_aborted_errors;
+		stats->tx_carrier_errors += pstats->tx_carrier_errors;
+		stats->tx_fifo_errors += pstats->tx_fifo_errors;
+		stats->tx_heartbeat_errors += pstats->tx_heartbeat_errors;
+		stats->tx_window_errors += pstats->tx_window_errors;
+	}
+	rcu_read_unlock();
+
+	return stats;
+}
+
+static void team_vlan_rx_add_vid(struct net_device *dev, uint16_t vid)
+{
+	struct team *team = netdev_priv(dev);
+	struct team_port *port;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(port, &team->port_list, list) {
+		const struct net_device_ops *ops = port->dev->netdev_ops;
+
+		ops->ndo_vlan_rx_add_vid(port->dev, vid);
+	}
+	rcu_read_unlock();
+}
+
+static void team_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid)
+{
+	struct team *team = netdev_priv(dev);
+	struct team_port *port;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(port, &team->port_list, list) {
+		const struct net_device_ops *ops = port->dev->netdev_ops;
+
+		ops->ndo_vlan_rx_kill_vid(port->dev, vid);
+	}
+	rcu_read_unlock();
+}
+
+static int team_add_slave(struct net_device *dev, struct net_device *port_dev)
+{
+	struct team *team = netdev_priv(dev);
+	int err;
+
+	spin_lock(&team->lock);
+	err = team_port_add(team, port_dev);
+	spin_unlock(&team->lock);
+	return err;
+}
+
+static int team_del_slave(struct net_device *dev, struct net_device *port_dev)
+{
+	struct team *team = netdev_priv(dev);
+	int err;
+
+	spin_lock(&team->lock);
+	err = team_port_del(team, port_dev);
+	spin_unlock(&team->lock);
+	return err;
+}
+
+static const struct net_device_ops team_netdev_ops = {
+	.ndo_init		= team_init,
+	.ndo_uninit		= team_uninit,
+	.ndo_open		= team_open,
+	.ndo_stop		= team_close,
+	.ndo_start_xmit		= team_xmit,
+	.ndo_change_rx_flags	= team_change_rx_flags,
+	.ndo_set_rx_mode	= team_set_rx_mode,
+	.ndo_set_mac_address	= team_set_mac_address,
+	.ndo_change_mtu		= team_change_mtu,
+	.ndo_get_stats64	= team_get_stats,
+	.ndo_vlan_rx_add_vid	= team_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid	= team_vlan_rx_kill_vid,
+	.ndo_add_slave		= team_add_slave,
+	.ndo_del_slave		= team_del_slave,
+};
+
+
+/***********************
+ * rt netlink interface
+ ***********************/
+
+static void team_setup(struct net_device *dev)
+{
+	ether_setup(dev);
+
+	dev->netdev_ops = &team_netdev_ops;
+	dev->destructor	= team_destructor;
+	dev->tx_queue_len = 0;
+	dev->flags |= IFF_MULTICAST;
+	dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
+
+	/*
+	 * Indicate we support unicast address filtering. That way core won't
+	 * bring us to promisc mode in case a unicast addr is added.
+	 * Let this up to underlay drivers.
+	 */
+	dev->priv_flags |= IFF_UNICAST_FLT;
+
+	dev->features |= NETIF_F_LLTX;
+	dev->features |= NETIF_F_GRO;
+	dev->hw_features = NETIF_F_HW_VLAN_TX |
+			   NETIF_F_HW_VLAN_RX |
+			   NETIF_F_HW_VLAN_FILTER;
+
+	dev->features |= dev->hw_features;
+}
+
+static int team_newlink(struct net *src_net, struct net_device *dev,
+			struct nlattr *tb[], struct nlattr *data[])
+{
+	int err;
+
+	if (tb[IFLA_ADDRESS] == NULL)
+		random_ether_addr(dev->dev_addr);
+
+	err = register_netdevice(dev);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int team_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+	if (tb[IFLA_ADDRESS]) {
+		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
+			return -EINVAL;
+		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
+			return -EADDRNOTAVAIL;
+	}
+	return 0;
+}
+
+static struct rtnl_link_ops team_link_ops __read_mostly = {
+	.kind		= DRV_NAME,
+	.priv_size	= sizeof(struct team),
+	.setup		= team_setup,
+	.newlink	= team_newlink,
+	.validate	= team_validate,
+};
+
+
+/***********************************
+ * Generic netlink custom interface
+ ***********************************/
+
+static struct genl_family team_nl_family = {
+	.id		= GENL_ID_GENERATE,
+	.name		= TEAM_GENL_NAME,
+	.version	= TEAM_GENL_VERSION,
+	.maxattr	= TEAM_ATTR_MAX,
+	.netnsok	= true,
+};
+
+static const struct nla_policy team_nl_policy[TEAM_ATTR_MAX + 1] = {
+	[TEAM_ATTR_UNSPEC]			= { .type = NLA_UNSPEC, },
+	[TEAM_ATTR_TEAM_IFINDEX]		= { .type = NLA_U32 },
+	[TEAM_ATTR_LIST_OPTION]			= { .type = NLA_NESTED },
+	[TEAM_ATTR_LIST_MODE]			= { .type = NLA_NESTED },
+	[TEAM_ATTR_LIST_PORT]			= { .type = NLA_NESTED },
+};
+
+static const struct nla_policy team_nl_option_policy[TEAM_ATTR_OPTION_MAX + 1] = {
+	[TEAM_ATTR_OPTION_UNSPEC]		= { .type = NLA_UNSPEC, },
+	[TEAM_ATTR_OPTION_NAME] = {
+		.type = NLA_STRING,
+		.len = TEAM_STRING_MAX_LEN,
+	},
+	[TEAM_ATTR_OPTION_CHANGED]		= { .type = NLA_FLAG },
+	[TEAM_ATTR_OPTION_TYPE]			= { .type = NLA_U8 },
+	[TEAM_ATTR_OPTION_DATA] = {
+		.type = NLA_BINARY,
+		.len = TEAM_STRING_MAX_LEN,
+	},
+};
+
+static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
+{
+	struct sk_buff *msg;
+	void *hdr;
+	int err;
+
+	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
+			  &team_nl_family, 0, TEAM_CMD_NOOP);
+	if (IS_ERR(hdr)) {
+		err = PTR_ERR(hdr);
+		goto err_msg_put;
+	}
+
+	genlmsg_end(msg, hdr);
+
+	return genlmsg_unicast(genl_info_net(info), msg, info->snd_pid);
+
+err_msg_put:
+	nlmsg_free(msg);
+
+	return err;
+}
+
+/*
+ * Netlink cmd functions should be locked by following two functions.
+ * To ensure team_uninit would not be called in between, hold rcu_read_lock
+ * all the time.
+ */
+static struct team *team_nl_team_get(struct genl_info *info)
+{
+	struct net *net = genl_info_net(info);
+	int ifindex;
+	struct net_device *dev;
+	struct team *team;
+
+	if (!info->attrs[TEAM_ATTR_TEAM_IFINDEX])
+		return NULL;
+
+	ifindex = nla_get_u32(info->attrs[TEAM_ATTR_TEAM_IFINDEX]);
+	rcu_read_lock();
+	dev = dev_get_by_index_rcu(net, ifindex);
+	if (!dev || dev->netdev_ops != &team_netdev_ops) {
+		rcu_read_unlock();
+		return NULL;
+	}
+
+	team = netdev_priv(dev);
+	spin_lock(&team->lock);
+	return team;
+}
+
+static void team_nl_team_put(struct team *team)
+{
+	spin_unlock(&team->lock);
+	rcu_read_unlock();
+}
+
+static int team_nl_send_generic(struct genl_info *info, struct team *team,
+				int (*fill_func)(struct sk_buff *skb,
+						 struct genl_info *info,
+						 int flags, struct team *team))
+{
+	struct sk_buff *skb;
+	int err;
+
+	skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+	if (!skb)
+		return -ENOMEM;
+
+	err = fill_func(skb, info, NLM_F_ACK, team);
+	if (err < 0)
+		goto err_fill;
+
+	err = genlmsg_unicast(genl_info_net(info), skb, info->snd_pid);
+	return err;
+
+err_fill:
+	nlmsg_free(skb);
+	return err;
+}
+
+static int team_nl_fill_options_get_changed(struct sk_buff *skb,
+					    u32 pid, u32 seq, int flags,
+					    struct team *team,
+					    struct team_option *changed_option)
+{
+	struct nlattr *option_list;
+	void *hdr;
+	struct team_option *option;
+
+	hdr = genlmsg_put(skb, pid, seq, &team_nl_family, flags,
+			  TEAM_CMD_OPTIONS_GET);
+	if (IS_ERR(hdr))
+		return PTR_ERR(hdr);
+
+	NLA_PUT_U32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex);
+	option_list = nla_nest_start(skb, TEAM_ATTR_LIST_OPTION);
+	if (!option_list)
+		return -EMSGSIZE;
+
+	list_for_each_entry(option, &team->option_list, list) {
+		struct nlattr *option_item;
+		long arg;
+
+		option_item = nla_nest_start(skb, TEAM_ATTR_ITEM_OPTION);
+		if (!option_item)
+			goto nla_put_failure;
+		NLA_PUT_STRING(skb, TEAM_ATTR_OPTION_NAME, option->name);
+		if (option == changed_option)
+			NLA_PUT_FLAG(skb, TEAM_ATTR_OPTION_CHANGED);
+		switch (option->type) {
+		case TEAM_OPTION_TYPE_U32:
+			NLA_PUT_U8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32);
+			team_option_get(team, option, &arg);
+			NLA_PUT_U32(skb, TEAM_ATTR_OPTION_DATA, arg);
+			break;
+		case TEAM_OPTION_TYPE_STRING:
+			NLA_PUT_U8(skb, TEAM_ATTR_OPTION_TYPE, NLA_STRING);
+			team_option_get(team, option, &arg);
+			NLA_PUT_STRING(skb, TEAM_ATTR_OPTION_DATA, (char *) arg);
+			break;
+		default:
+			BUG();
+		}
+		nla_nest_end(skb, option_item);
+	}
+
+	nla_nest_end(skb, option_list);
+	return genlmsg_end(skb, hdr);
+
+nla_put_failure:
+	genlmsg_cancel(skb, hdr);
+	return -EMSGSIZE;
+}
+
+static int team_nl_fill_options_get(struct sk_buff *skb,
+				    struct genl_info *info, int flags,
+				    struct team *team)
+{
+	return team_nl_fill_options_get_changed(skb, info->snd_pid,
+						info->snd_seq, NLM_F_ACK,
+						team, NULL);
+}
+
+static int team_nl_cmd_options_get(struct sk_buff *skb, struct genl_info *info)
+{
+	struct team *team;
+	int err;
+
+	team = team_nl_team_get(info);
+	if (!team)
+		return -EINVAL;
+
+	err = team_nl_send_generic(info, team, team_nl_fill_options_get);
+
+	team_nl_team_put(team);
+
+	return err;
+}
+
+static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
+{
+	struct team *team;
+	int err = 0;
+	int i;
+	struct nlattr *nl_option;
+
+	team = team_nl_team_get(info);
+	if (!team)
+		return -EINVAL;
+
+	err = -EINVAL;
+	if (!info->attrs[TEAM_ATTR_LIST_OPTION]) {
+		err = -EINVAL;
+		goto team_put;
+	}
+
+	nla_for_each_nested(nl_option, info->attrs[TEAM_ATTR_LIST_OPTION], i) {
+		struct nlattr *mode_attrs[TEAM_ATTR_OPTION_MAX + 1];
+		enum team_option_type opt_type;
+		struct team_option *option;
+		char *opt_name;
+
+		if (nla_type(nl_option) != TEAM_ATTR_ITEM_OPTION) {
+			err = -EINVAL;
+			goto team_put;
+		}
+		err = nla_parse_nested(mode_attrs, TEAM_ATTR_OPTION_MAX,
+				       nl_option, team_nl_option_policy);
+		if (err)
+			goto team_put;
+		if (!mode_attrs[TEAM_ATTR_OPTION_NAME] ||
+		    !mode_attrs[TEAM_ATTR_OPTION_TYPE] ||
+		    !mode_attrs[TEAM_ATTR_OPTION_DATA]) {
+			err = -EINVAL;
+			goto team_put;
+		}
+		switch (nla_get_u8(mode_attrs[TEAM_ATTR_OPTION_TYPE])) {
+		case NLA_U32:
+			opt_type = TEAM_OPTION_TYPE_U32;
+			break;
+		case NLA_STRING:
+			opt_type = TEAM_OPTION_TYPE_STRING;
+			break;
+		default:
+			goto team_put;
+		}
+
+		opt_name = nla_data(mode_attrs[TEAM_ATTR_OPTION_NAME]);
+		list_for_each_entry(option, &team->option_list, list) {
+			long arg;
+
+			if (option->type != opt_type ||
+			    strcmp(option->name, opt_name))
+				continue;
+			switch (opt_type) {
+			case TEAM_OPTION_TYPE_U32:
+				arg = nla_get_u32(mode_attrs[TEAM_ATTR_OPTION_DATA]);
+				break;
+			case TEAM_OPTION_TYPE_STRING:
+				arg = (long) nla_data(mode_attrs[TEAM_ATTR_OPTION_DATA]);
+				break;
+			default:
+				BUG();
+			}
+			err = team_option_set(team, option, &arg);
+			if (err)
+				goto team_put;
+		}
+	}
+
+team_put:
+	team_nl_team_put(team);
+
+	return err;
+}
+
+static int team_nl_fill_mode_list_get(struct sk_buff *skb,
+				      struct genl_info *info, int flags,
+				      struct team *team)
+{
+	struct nlattr *mode_list;
+	void *hdr;
+	int i;
+
+	hdr = genlmsg_put(skb, info->snd_pid, info->snd_seq,
+			  &team_nl_family, flags, TEAM_CMD_MODE_LIST_GET);
+	if (IS_ERR(hdr))
+		return PTR_ERR(hdr);
+
+	NLA_PUT_U32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex);
+	mode_list = nla_nest_start(skb, TEAM_ATTR_LIST_MODE);
+	if (!mode_list)
+		return -EMSGSIZE;
+
+	for (i = 0; i < team_mode_count; i++) {
+		const struct team_mode *mode  = team_modes[i];
+		struct nlattr *mode_item;
+
+		mode_item = nla_nest_start(skb, TEAM_ATTR_ITEM_MODE);
+		if (!mode_item)
+			goto nla_put_failure;
+		NLA_PUT_STRING(skb, TEAM_ATTR_MODE_NAME, mode->kind);
+		nla_nest_end(skb, mode_item);
+	}
+
+	nla_nest_end(skb, mode_list);
+	return genlmsg_end(skb, hdr);
+
+nla_put_failure:
+	genlmsg_cancel(skb, hdr);
+	return -EMSGSIZE;
+}
+
+static int team_nl_cmd_mode_list_get(struct sk_buff *skb,
+				     struct genl_info *info)
+{
+	struct team *team;
+	int err;
+
+	team = team_nl_team_get(info);
+	if (!team)
+		return -EINVAL;
+
+	err = team_nl_send_generic(info, team, team_nl_fill_mode_list_get);
+
+	team_nl_team_put(team);
+
+	return err;
+}
+
+static int team_nl_fill_port_list_get_changed(struct sk_buff *skb,
+					      u32 pid, u32 seq, int flags,
+					      struct team *team,
+					      struct team_port *changed_port)
+{
+	struct nlattr *port_list;
+	void *hdr;
+	struct team_port *port;
+
+	hdr = genlmsg_put(skb, pid, seq, &team_nl_family, flags,
+			  TEAM_CMD_PORT_LIST_GET);
+	if (IS_ERR(hdr))
+		return PTR_ERR(hdr);
+
+	NLA_PUT_U32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex);
+	port_list = nla_nest_start(skb, TEAM_ATTR_LIST_PORT);
+	if (!port_list)
+		return -EMSGSIZE;
+
+	list_for_each_entry_rcu(port, &team->port_list, list) {
+		struct nlattr *port_item;
+
+		port_item = nla_nest_start(skb, TEAM_ATTR_ITEM_MODE);
+		if (!port_item)
+			goto nla_put_failure;
+		NLA_PUT_U32(skb, TEAM_ATTR_PORT_IFINDEX, port->dev->ifindex);
+		if (port == changed_port)
+			NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_CHANGED);
+		if (port->linkup)
+			NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_LINKUP);
+		NLA_PUT_U32(skb, TEAM_ATTR_PORT_SPEED, port->speed);
+		NLA_PUT_U8(skb, TEAM_ATTR_PORT_DUPLEX, port->duplex);
+		nla_nest_end(skb, port_item);
+	}
+
+	nla_nest_end(skb, port_list);
+	return genlmsg_end(skb, hdr);
+
+nla_put_failure:
+	genlmsg_cancel(skb, hdr);
+	return -EMSGSIZE;
+}
+
+static int team_nl_fill_port_list_get(struct sk_buff *skb,
+				      struct genl_info *info, int flags,
+				      struct team *team)
+{
+	return team_nl_fill_port_list_get_changed(skb, info->snd_pid,
+						  info->snd_seq, NLM_F_ACK,
+						  team, NULL);
+}
+
+static int team_nl_cmd_port_list_get(struct sk_buff *skb,
+				     struct genl_info *info)
+{
+	struct team *team;
+	int err;
+
+	team = team_nl_team_get(info);
+	if (!team)
+		return -EINVAL;
+
+	err = team_nl_send_generic(info, team, team_nl_fill_port_list_get);
+
+	team_nl_team_put(team);
+
+	return err;
+}
+
+static struct genl_ops team_nl_ops[] = {
+	{
+		.cmd = TEAM_CMD_NOOP,
+		.doit = team_nl_cmd_noop,
+		.policy = team_nl_policy,
+	},
+	{
+		.cmd = TEAM_CMD_OPTIONS_SET,
+		.doit = team_nl_cmd_options_set,
+		.policy = team_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = TEAM_CMD_OPTIONS_GET,
+		.doit = team_nl_cmd_options_get,
+		.policy = team_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = TEAM_CMD_MODE_LIST_GET,
+		.doit = team_nl_cmd_mode_list_get,
+		.policy = team_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = TEAM_CMD_PORT_LIST_GET,
+		.doit = team_nl_cmd_port_list_get,
+		.policy = team_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+};
+
+static struct genl_multicast_group team_change_event_mcgrp = {
+	.name = TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME,
+};
+
+static int team_nl_send_event_options_get(struct team *team,
+					  struct team_option *changed_option)
+{
+	struct sk_buff *skb;
+	int err;
+	struct net *net = dev_net(team->dev);
+
+	skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+	if (!skb)
+		return -ENOMEM;
+
+	err = team_nl_fill_options_get_changed(skb, 0, 0, 0, team,
+					       changed_option);
+	if (err < 0)
+		goto err_fill;
+
+	err = genlmsg_multicast_netns(net, skb, 0, team_change_event_mcgrp.id,
+				      GFP_KERNEL);
+	return err;
+
+err_fill:
+	nlmsg_free(skb);
+	return err;
+}
+
+static int team_nl_send_event_port_list_get(struct team_port *port)
+{
+	struct sk_buff *skb;
+	int err;
+	struct net *net = dev_net(port->team->dev);
+
+	skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+	if (!skb)
+		return -ENOMEM;
+
+	err = team_nl_fill_port_list_get_changed(skb, 0, 0, 0,
+						 port->team, port);
+	if (err < 0)
+		goto err_fill;
+
+	err = genlmsg_multicast_netns(net, skb, 0, team_change_event_mcgrp.id,
+				      GFP_KERNEL);
+	return err;
+
+err_fill:
+	nlmsg_free(skb);
+	return err;
+}
+
+static int team_nl_init(void)
+{
+	int err;
+
+	err = genl_register_family_with_ops(&team_nl_family, team_nl_ops,
+					    ARRAY_SIZE(team_nl_ops));
+	if (err)
+		return err;
+
+	err = genl_register_mc_group(&team_nl_family, &team_change_event_mcgrp);
+	if (err)
+		goto err_change_event_grp_reg;
+
+	return 0;
+
+err_change_event_grp_reg:
+	genl_unregister_family(&team_nl_family);
+
+	return err;
+}
+
+static void team_nl_fini(void)
+{
+	genl_unregister_family(&team_nl_family);
+}
+
+
+/******************
+ * Change checkers
+ ******************/
+
+static void __team_options_change_check(struct team *team,
+					struct team_option *changed_option)
+{
+	int err;
+
+	err = team_nl_send_event_options_get(team, changed_option);
+	if (err)
+		netdev_warn(team->dev, "Failed to send options change "
+				       "via netlink\n");
+}
+
+/* rtnl lock is held */
+static void __team_port_change_check(struct team_port *port, bool linkup)
+{
+	int err;
+
+	if (port->linkup == linkup)
+		return;
+
+	port->linkup = linkup;
+	if (linkup) {
+		struct ethtool_cmd ecmd;
+
+		err = __ethtool_get_settings(port->dev, &ecmd);
+		if (!err) {
+			port->speed = ethtool_cmd_speed(&ecmd);
+			port->duplex = ecmd.duplex;
+			goto send_event;
+		}
+	}
+	port->speed = 0;
+	port->duplex = 0;
+
+send_event:
+	err = team_nl_send_event_port_list_get(port);
+	if (err)
+		netdev_warn(port->team->dev, "Failed to send port change of "
+					     "device %s via netlink\n",
+			    port->dev->name);
+
+}
+
+static void team_port_change_check(struct team_port *port, bool linkup)
+{
+	struct team *team = port->team;
+
+	spin_lock(&team->lock);
+	__team_port_change_check(port, linkup);
+	spin_unlock(&team->lock);
+}
+
+/************************************
+ * Net device notifier event handler
+ ************************************/
+
+static int team_device_event(struct notifier_block *unused,
+			     unsigned long event, void *ptr)
+{
+	struct net_device *dev = (struct net_device *) ptr;
+	struct team_port *port;
+
+	port = team_port_get_rtnl(dev);
+	if (!port)
+		return NOTIFY_DONE;
+
+	switch (event) {
+	case NETDEV_UP:
+		if (netif_carrier_ok(dev));
+			team_port_change_check(port, true);
+	case NETDEV_DOWN:
+		team_port_change_check(port, false);
+	case NETDEV_CHANGE:
+		if (netif_running(port->dev))
+			team_port_change_check(port,
+					       !!netif_carrier_ok(port->dev));
+		break;
+	case NETDEV_UNREGISTER:
+		team_del_slave(port->team->dev, dev);
+		break;
+	case NETDEV_CHANGEMTU:
+		/* Forbid to change mtu of underlaying device */
+		return NOTIFY_BAD;
+	case NETDEV_CHANGEADDR:
+		/* Forbid to change addr of underlaying device */
+		return NOTIFY_BAD;
+	case NETDEV_PRE_TYPE_CHANGE:
+		/* Forbid to change type of underlaying device */
+		return NOTIFY_BAD;
+	}
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block team_notifier_block __read_mostly = {
+	.notifier_call = team_device_event,
+};
+
+
+/***********************
+ * Module init and exit
+ ***********************/
+
+static int __init team_module_init(void)
+{
+	int err;
+
+	register_netdevice_notifier(&team_notifier_block);
+
+	err = rtnl_link_register(&team_link_ops);
+	if (err)
+		goto err_rtln_reg;
+
+	err = team_nl_init();
+	if (err)
+		goto err_nl_init;
+
+	return 0;
+
+err_nl_init:
+	rtnl_link_unregister(&team_link_ops);
+
+err_rtln_reg:
+	unregister_netdevice_notifier(&team_notifier_block);
+
+	return err;
+}
+
+static void __exit team_module_exit(void)
+{
+	team_nl_fini();
+	rtnl_link_unregister(&team_link_ops);
+	unregister_netdevice_notifier(&team_notifier_block);
+}
+
+module_init(team_module_init);
+module_exit(team_module_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Jiri Pirko <jpirko@redhat.com>");
+MODULE_DESCRIPTION("Ethernet team device driver");
+MODULE_ALIAS_RTNL_LINK(DRV_NAME);
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 619b565..0b091b3 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -185,6 +185,7 @@ header-y += if_pppol2tp.h
 header-y += if_pppox.h
 header-y += if_slip.h
 header-y += if_strip.h
+header-y += if_team.h
 header-y += if_tr.h
 header-y += if_tun.h
 header-y += if_tunnel.h
diff --git a/include/linux/if.h b/include/linux/if.h
index db20bd4..e98f39d 100644
--- a/include/linux/if.h
+++ b/include/linux/if.h
@@ -79,6 +79,7 @@
 #define IFF_TX_SKB_SHARING	0x10000	/* The interface supports sharing
 					 * skbs on transmit */
 #define IFF_UNICAST_FLT	0x20000		/* Supports unicast filtering	*/
+#define IFF_TEAM_PORT	0x40000		/* device used as teaming port */
 
 #define IF_GET_IFACE	0x0001		/* for querying only */
 #define IF_GET_PROTO	0x0002
diff --git a/include/linux/if_team.h b/include/linux/if_team.h
new file mode 100644
index 0000000..b451c9e
--- /dev/null
+++ b/include/linux/if_team.h
@@ -0,0 +1,126 @@
+/*
+ * include/linux/if_team.h - Network team device driver header
+ * Copyright (c) 2011 Jiri Pirko <jpirko@redhat.com>
+ *
+ * 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 Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _LINUX_IF_TEAM_H_
+#define _LINUX_IF_TEAM_H_
+
+#define TEAM_STRING_MAX_LEN 32
+
+/**********************************
+ * NETLINK_GENERIC netlink family.
+ **********************************/
+
+enum {
+	TEAM_CMD_NOOP,
+	TEAM_CMD_OPTIONS_SET,
+	TEAM_CMD_OPTIONS_GET,
+	TEAM_CMD_MODE_LIST_GET,
+	TEAM_CMD_PORT_LIST_GET,
+
+	__TEAM_CMD_MAX,
+	TEAM_CMD_MAX = (__TEAM_CMD_MAX - 1),
+};
+
+enum {
+	TEAM_ATTR_UNSPEC,
+	TEAM_ATTR_TEAM_IFINDEX,		/* u32 */
+	TEAM_ATTR_LIST_OPTION,		/* nest */
+	TEAM_ATTR_LIST_MODE,		/* nest */
+	TEAM_ATTR_LIST_PORT,		/* nest */
+
+	__TEAM_ATTR_MAX,
+	TEAM_ATTR_MAX = __TEAM_ATTR_MAX - 1,
+};
+
+/* Nested layout of get/set msg:
+ *
+ *	[TEAM_ATTR_LIST_OPTION]
+ *		[TEAM_ATTR_ITEM_OPTION]
+ *			[TEAM_ATTR_OPTION_*], ...
+ *		[TEAM_ATTR_ITEM_OPTION]
+ *			[TEAM_ATTR_OPTION_*], ...
+ *		...
+ *	[TEAM_ATTR_LIST_MODE]
+ *		[TEAM_ATTR_ITEM_MODE]
+ *			[TEAM_ATTR_MODE_*], ...
+ *		[TEAM_ATTR_ITEM_MODE]
+ *			[TEAM_ATTR_MODE_*], ...
+ *		...
+ *	[TEAM_ATTR_LIST_PORT]
+ *		[TEAM_ATTR_ITEM_PORT]
+ *			[TEAM_ATTR_PORT_*], ...
+ *		[TEAM_ATTR_ITEM_PORT]
+ *			[TEAM_ATTR_PORT_*], ...
+ *		...
+ */
+
+enum {
+	TEAM_ATTR_ITEM_OPTION_UNSPEC,
+	TEAM_ATTR_ITEM_OPTION,		/* nest */
+
+	__TEAM_ATTR_ITEM_OPTION_MAX,
+	TEAM_ATTR_ITEM_OPTION_MAX = __TEAM_ATTR_ITEM_OPTION_MAX - 1,
+};
+
+enum {
+	TEAM_ATTR_OPTION_UNSPEC,
+	TEAM_ATTR_OPTION_NAME,		/* string */
+	TEAM_ATTR_OPTION_CHANGED,	/* flag */
+	TEAM_ATTR_OPTION_TYPE,		/* u8 */
+	TEAM_ATTR_OPTION_DATA,		/* dynamic */
+
+	__TEAM_ATTR_OPTION_MAX,
+	TEAM_ATTR_OPTION_MAX = __TEAM_ATTR_OPTION_MAX - 1,
+};
+
+enum {
+	TEAM_ATTR_ITEM_MODE_UNSPEC,
+	TEAM_ATTR_ITEM_MODE,		/* nest */
+
+	__TEAM_ATTR_ITEM_MODE_MAX,
+	TEAM_ATTR_ITEM_MODE_MAX = __TEAM_ATTR_ITEM_MODE_MAX - 1,
+};
+
+enum {
+	TEAM_ATTR_MODE_UNSPEC,
+	TEAM_ATTR_MODE_NAME,		/* string */
+
+	__TEAM_ATTR_MODE_MAX,
+	TEAM_ATTR_MODE_MAX = __TEAM_ATTR_MODE_MAX - 1,
+};
+
+enum {
+	TEAM_ATTR_ITEM_PORT_UNSPEC,
+	TEAM_ATTR_ITEM_PORT,		/* nest */
+
+	__TEAM_ATTR_ITEM_PORT_MAX,
+	TEAM_ATTR_ITEM_PORT_MAX = __TEAM_ATTR_ITEM_PORT_MAX - 1,
+};
+
+enum {
+	TEAM_ATTR_PORT_UNSPEC,
+	TEAM_ATTR_PORT_IFINDEX,		/* u32 */
+	TEAM_ATTR_PORT_CHANGED,		/* flag */
+	TEAM_ATTR_PORT_LINKUP,		/* flag */
+	TEAM_ATTR_PORT_SPEED,		/* u32 */
+	TEAM_ATTR_PORT_DUPLEX,		/* u8 */
+
+	__TEAM_ATTR_PORT_MAX,
+	TEAM_ATTR_PORT_MAX = __TEAM_ATTR_PORT_MAX - 1,
+};
+
+/*
+ * NETLINK_GENERIC related info
+ */
+#define TEAM_GENL_NAME "team"
+#define TEAM_GENL_VERSION 0x1
+#define TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME "change_event"
+
+#endif
-- 
1.7.6

^ permalink raw reply related

* Re: conntrack events over netlink flood
From: Florian Westphal @ 2011-09-30 12:59 UTC (permalink / raw)
  To: Denys Fedoryshchenko; +Cc: netdev, netfilter-devel
In-Reply-To: <069917f11e06f3cf2e1ce9715f435b61@visp.net.lb>

Denys Fedoryshchenko <denys@visp.net.lb> wrote:

[ cc: netfilter-devel ]

>  After enabling events and running conntrack -E i notice flood in output 
>  of server that have PPPoE and PPTP connections. Here is the output:
> 
>  OfficeNAT ~ # conntrack  -E
>   [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
>  srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
>  dstkey=0x0 [ASSURED]
>   [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1 
>  srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3 
>  dstkey=0x0 [ASSURED]

[..]

>  Is it considered as a bug? I think it should not send on each packet 
>  conntrack event.

Bug. Update events should only be generated when something in the
conntrack has changed (e.g. the connmark).

Could you please try this patch (untested)?

Subject: [PATCH] netfilter: conntrack_gre: only create ct assured event once

diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -241,8 +241,8 @@ static int gre_packet(struct nf_conn *ct,
 		nf_ct_refresh_acct(ct, ctinfo, skb,
 				   ct->proto.gre.stream_timeout);
 		/* Also, more likely to be important, and not a probe. */
-		set_bit(IPS_ASSURED_BIT, &ct->status);
-		nf_conntrack_event_cache(IPCT_ASSURED, ct);
+		if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
+			nf_conntrack_event_cache(IPCT_ASSURED, ct);
 	} else
 		nf_ct_refresh_acct(ct, ctinfo, skb,
 				   ct->proto.gre.timeout);

^ permalink raw reply

* [PATCH] mlx4_en: fix transmit of packages when blue frame is enabled
From: Thadeu Lima de Souza Cascardo @ 2011-09-30 13:23 UTC (permalink / raw)
  To: netdev; +Cc: Thadeu Lima de Souza Cascardo, Yevgeny Petrilin

With the addition of Blue Frame support in the network driver for mlx4,
the doorbell is not written in the path where blue frame is enabled and
the package follows some characteristics.

The consequence of that is that ICMP ECHO requests, for example, were
not transmitted by the device. A ping flood, for example, would make the
watchdog dispatch, because the ring was full and transmissions have
timed out.

After this fix, I could ping two systems using mlx4_en (both with the
fix).

Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
Cc: Yevgeny Petrilin <yevgenyp@mellanox.co.il>
---
 drivers/net/ethernet/mellanox/mlx4/en_tx.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 6e03de0..270da80 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -811,10 +811,11 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
 		* before setting ownership of this descriptor to HW */
 		wmb();
 		tx_desc->ctrl.owner_opcode = op_own;
-		wmb();
-		writel(ring->doorbell_qpn, ring->bf.uar->map + MLX4_SEND_DOORBELL);
 	}
 
+	wmb();
+	writel(ring->doorbell_qpn, ring->bf.uar->map + MLX4_SEND_DOORBELL);
+
 	/* Poll CQ here */
 	mlx4_en_xmit_poll(priv, tx_ind);
 
-- 
1.7.4.4

^ permalink raw reply related

* Re: conntrack events over netlink flood
From: Denys Fedoryshchenko @ 2011-09-30 13:46 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netdev, netfilter-devel
In-Reply-To: <20110930125956.GD13047@Chamillionaire.breakpoint.cc>

 On Fri, 30 Sep 2011 14:59:56 +0200, Florian Westphal wrote:
> Denys Fedoryshchenko <denys@visp.net.lb> wrote:
>
> [ cc: netfilter-devel ]
>
>>  After enabling events and running conntrack -E i notice flood in 
>> output
>>  of server that have PPPoE and PPTP connections. Here is the output:
>>
>>  OfficeNAT ~ # conntrack  -E
>>   [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1
>>  srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3
>>  dstkey=0x0 [ASSURED]
>>   [UPDATE] gre      47 17999 src=192.168.0.140 dst=192.168.0.1
>>  srckey=0x0 dstkey=0x3 src=192.168.0.1 dst=192.168.0.140 srckey=0x3
>>  dstkey=0x0 [ASSURED]
>
> [..]
>
>>  Is it considered as a bug? I think it should not send on each 
>> packet
>>  conntrack event.
>
> Bug. Update events should only be generated when something in the
> conntrack has changed (e.g. the connmark).
>
> Could you please try this patch (untested)?
>
> Subject: [PATCH] netfilter: conntrack_gre: only create ct assured 
> event once
>
> diff --git a/net/netfilter/nf_conntrack_proto_gre.c
> b/net/netfilter/nf_conntrack_proto_gre.c
> --- a/net/netfilter/nf_conntrack_proto_gre.c
> +++ b/net/netfilter/nf_conntrack_proto_gre.c
> @@ -241,8 +241,8 @@ static int gre_packet(struct nf_conn *ct,
>  		nf_ct_refresh_acct(ct, ctinfo, skb,
>  				   ct->proto.gre.stream_timeout);
>  		/* Also, more likely to be important, and not a probe. */
> -		set_bit(IPS_ASSURED_BIT, &ct->status);
> -		nf_conntrack_event_cache(IPCT_ASSURED, ct);
> +		if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
> +			nf_conntrack_event_cache(IPCT_ASSURED, ct);
>  	} else
>  		nf_ct_refresh_acct(ct, ctinfo, skb,
>  				   ct->proto.gre.timeout);
 Fine now, patch fixed this bug.

 Tested-by: Denys Fedoryshchenko <denys@visp.net.lb>

 ---
 System administrator
 Denys Fedoryshchenko
 Virtual ISP S.A.L.

^ permalink raw reply

* Re: [net-next 11/11] ixgbe: allow eeprom writes via ethtool
From: Ben Hutchings @ 2011-09-30 13:52 UTC (permalink / raw)
  To: Jeff Kirsher; +Cc: davem, Emil Tantilov, netdev, gospo
In-Reply-To: <1317360291-5576-12-git-send-email-jeffrey.t.kirsher@intel.com>

On Thu, 2011-09-29 at 22:24 -0700, Jeff Kirsher wrote:
[...]
> +static int ixgbe_set_eeprom(struct net_device *netdev,
> +			    struct ethtool_eeprom *eeprom, u8 *bytes)
> +{
> +	struct ixgbe_adapter *adapter = netdev_priv(netdev);
> +	struct ixgbe_hw *hw = &adapter->hw;
> +	u16 *eeprom_buff;
> +	void *ptr;
> +	int max_len, first_word, last_word, ret_val = 0;
> +	u16 i;
> +
> +	if (eeprom->len == 0)
> +		return -EOPNOTSUPP;
> +
> +	if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
> +		return -EFAULT;
[...]

Both these error codes should be EINVAL.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* Re: [PATCH next 2/7] 8139cp : removal of headers.
From: Ben Hutchings @ 2011-09-30 14:03 UTC (permalink / raw)
  To: Francois Romieu; +Cc: davem, netdev
In-Reply-To: <20110930103719.GC26727@electric-eye.fr.zoreil.com>

On Fri, 2011-09-30 at 12:37 +0200, Francois Romieu wrote:
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> ---
>  drivers/net/ethernet/realtek/8139cp.c |    5 -----
>  1 files changed, 0 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
> index c77d5af..60c8de5 100644
> --- a/drivers/net/ethernet/realtek/8139cp.c
> +++ b/drivers/net/ethernet/realtek/8139cp.c
> @@ -55,8 +55,6 @@
>  
>  #include <linux/module.h>
>  #include <linux/moduleparam.h>
> -#include <linux/kernel.h>

Needed for container_of.

> -#include <linux/compiler.h>

Needed for __packed.  But it's probably safe to assume that
<linux/kernel.h> will include it.

>  #include <linux/netdevice.h>
>  #include <linux/etherdevice.h>
>  #include <linux/init.h>
> @@ -65,7 +63,6 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/delay.h>
>  #include <linux/ethtool.h>
> -#include <linux/gfp.h>

Needed for GFP_KERNEL.

>  #include <linux/mii.h>
>  #include <linux/if_vlan.h>
>  #include <linux/crc32.h>
> @@ -73,10 +70,8 @@
>  #include <linux/ip.h>
>  #include <linux/tcp.h>
>  #include <linux/udp.h>
> -#include <linux/cache.h>

Needed for ____cacheline_aligned.

>  #include <asm/io.h>
>  #include <asm/irq.h>
> -#include <asm/uaccess.h>
>  
>  /* These identify the driver base version and may not be removed. */
>  static char version[] =

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox