void netdev_attach_ops(struct net_device *dev,
const struct net_device_ops *ops)
{
+ if (!ops)
+ return;
+
dev->open = ops->ndo_open;
dev->init = ops->ndo_init;
dev->stop = ops->ndo_stop;
--- /dev/null
+
+This patch backports the struct net_device_ops changes added on 2.6.29.
+
+If we add the compat.git netdev_attach_ops() implementation
+for newer kernels upstream it means we do not have to use this
+patch at all for older kernels.
+
+mcgrof@tux ~/linux-stable (git::master)$ git describe --contains d314774cf2cd5dfeb39a00d37deee65d4c627927
+v2.6.29-rc1~581^2~677
+
+commit d314774cf2cd5dfeb39a00d37deee65d4c627927
+Author: Stephen Hemminger <shemminger@vyatta.com>
+Date: Wed Nov 19 21:32:24 2008 -0800
+
+ netdev: network device operations infrastructure
+
+ This patch changes the network device internal API to move adminstrative
+ operations out of the network device structure and into a separate structure.
+
+ This patch involves some hackery to maintain compatablity between the
+ new and old model, so all 300+ drivers don't have to be changed at once.
+ For drivers that aren't converted yet, the netdevice_ops virt function list
+ still resides in the net_device structure. For old protocols, the new
+ net_device_ops are copied out to the old net_device pointers.
+
+ After the transistion is completed the nag message can be changed to
+ an WARN_ON, and the compatiablity code can be made configurable.
+
+ Some function pointers aren't moved:
+ * destructor can't be in net_device_ops because
+ it may need to be referenced after the module is unloaded.
+ * neighbor setup is manipulated in a couple of places that need special
+ consideration
+ * hard_start_xmit is in the fast path for transmit.
+
+ Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+--- a/net/wireless/wext-core.c
++++ b/net/wireless/wext-core.c
+@@ -925,9 +925,7 @@ static int wireless_process_ioctl(struct
+ return private(dev, iwr, cmd, info, handler);
+ }
+ /* Old driver API : call driver ioctl handler */
+- if (dev->netdev_ops->ndo_do_ioctl)
+- return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd);
+- return -EOPNOTSUPP;
++ return ndo_do_ioctl(dev, ifr, cmd);
+ }
+
+ /* If command is `set a parameter', or `get the encoding parameters',
--- /dev/null
+@@
+expression dev;
+expression ops;
+@@
+-dev->netdev_ops = ops;
++netdev_attach_ops(dev, ops);
+++ /dev/null
-
-This patch backports the struct net_device_ops changes added on 2.6.29.
-
-If we add the compat.git netdev_attach_ops() implementation
-for newer kernels upstream it means we do not have to use this
-patch at all for older kernels.
-
-mcgrof@tux ~/linux-stable (git::master)$ git describe --contains d314774cf2cd5dfeb39a00d37deee65d4c627927
-v2.6.29-rc1~581^2~677
-
-commit d314774cf2cd5dfeb39a00d37deee65d4c627927
-Author: Stephen Hemminger <shemminger@vyatta.com>
-Date: Wed Nov 19 21:32:24 2008 -0800
-
- netdev: network device operations infrastructure
-
- This patch changes the network device internal API to move adminstrative
- operations out of the network device structure and into a separate structure.
-
- This patch involves some hackery to maintain compatablity between the
- new and old model, so all 300+ drivers don't have to be changed at once.
- For drivers that aren't converted yet, the netdevice_ops virt function list
- still resides in the net_device structure. For old protocols, the new
- net_device_ops are copied out to the old net_device pointers.
-
- After the transistion is completed the nag message can be changed to
- an WARN_ON, and the compatiablity code can be made configurable.
-
- Some function pointers aren't moved:
- * destructor can't be in net_device_ops because
- it may need to be referenced after the module is unloaded.
- * neighbor setup is manipulated in a couple of places that need special
- consideration
- * hard_start_xmit is in the fast path for transmit.
-
- Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
- Signed-off-by: David S. Miller <davem@davemloft.net>
-
+++ /dev/null
---- a/drivers/net/ethernet/atheros/alx/main.c
-+++ b/drivers/net/ethernet/atheros/alx/main.c
-@@ -1256,7 +1256,7 @@ static int alx_probe(struct pci_dev *pde
- goto out_free_netdev;
- }
-
-- netdev->netdev_ops = &alx_netdev_ops;
-+ netdev_attach_ops(netdev, &alx_netdev_ops);
- SET_ETHTOOL_OPS(netdev, &alx_ethtool_ops);
- netdev->irq = pdev->irq;
- netdev->watchdog_timeo = ALX_WATCHDOG_TIME;
+++ /dev/null
---- a/drivers/net/wireless/ath/ath6kl/main.c
-+++ b/drivers/net/wireless/ath/ath6kl/main.c
-@@ -1292,7 +1292,7 @@ static const struct net_device_ops ath6k
-
- void init_netdev(struct net_device *dev)
- {
-- dev->netdev_ops = &ath6kl_netdev_ops;
-+ netdev_attach_ops(dev, &ath6kl_netdev_ops);
- dev->destructor = free_netdev;
- dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
-
+++ /dev/null
---- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
-+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
-@@ -2508,7 +2508,7 @@ static int atl1c_init_netdev(struct net_
- SET_NETDEV_DEV(netdev, &pdev->dev);
- pci_set_drvdata(pdev, netdev);
-
-- netdev->netdev_ops = &atl1c_netdev_ops;
-+ netdev_attach_ops(netdev, &atl1c_netdev_ops);
- netdev->watchdog_timeo = AT_TX_WATCHDOG;
- atl1c_set_ethtool_ops(netdev);
-
+++ /dev/null
---- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
-+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
-@@ -2273,7 +2273,7 @@ static int atl1e_init_netdev(struct net_
- SET_NETDEV_DEV(netdev, &pdev->dev);
- pci_set_drvdata(pdev, netdev);
-
-- netdev->netdev_ops = &atl1e_netdev_ops;
-+ netdev_attach_ops(netdev, &atl1e_netdev_ops);
-
- netdev->watchdog_timeo = AT_TX_WATCHDOG;
- atl1e_set_ethtool_ops(netdev);
+++ /dev/null
---- a/drivers/net/ethernet/atheros/atlx/atl1.c
-+++ b/drivers/net/ethernet/atheros/atlx/atl1.c
-@@ -3004,7 +3004,7 @@ static int atl1_probe(struct pci_dev *pd
- adapter->mii.phy_id_mask = 0x1f;
- adapter->mii.reg_num_mask = 0x1f;
-
-- netdev->netdev_ops = &atl1_netdev_ops;
-+ netdev_attach_ops(netdev, &atl1_netdev_ops);
- netdev->watchdog_timeo = 5 * HZ;
- netif_napi_add(netdev, &adapter->napi, atl1_rings_clean, 64);
-
---- a/drivers/net/ethernet/atheros/atlx/atl2.c
-+++ b/drivers/net/ethernet/atheros/atlx/atl2.c
-@@ -1396,7 +1396,7 @@ static int atl2_probe(struct pci_dev *pd
-
- atl2_setup_pcicmd(pdev);
-
-- netdev->netdev_ops = &atl2_netdev_ops;
-+ netdev_attach_ops(netdev, &atl2_netdev_ops);
- atl2_set_ethtool_ops(netdev);
- netdev->watchdog_timeo = 5 * HZ;
- strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
+++ /dev/null
---- a/drivers/net/ethernet/broadcom/b44.c
-+++ b/drivers/net/ethernet/broadcom/b44.c
-@@ -2180,7 +2180,7 @@ static int b44_init_one(struct ssb_devic
- bp->rx_pending = B44_DEF_RX_RING_PENDING;
- bp->tx_pending = B44_DEF_TX_RING_PENDING;
-
-- dev->netdev_ops = &b44_netdev_ops;
-+ netdev_attach_ops(dev, &b44_netdev_ops);
- netif_napi_add(dev, &bp->napi, b44_poll, 64);
- dev->watchdog_timeo = B44_TX_TIMEOUT;
- dev->irq = sdev->irq;
+++ /dev/null
---- a/net/bluetooth/bnep/netdev.c
-+++ b/net/bluetooth/bnep/netdev.c
-@@ -223,7 +223,7 @@ void bnep_net_setup(struct net_device *d
-
- ether_setup(dev);
- dev->priv_flags &= ~IFF_TX_SKB_SHARING;
-- dev->netdev_ops = &bnep_netdev_ops;
-+ netdev_attach_ops(dev, &bnep_netdev_ops);
-
- dev->watchdog_timeo = HZ * 2;
- }
+++ /dev/null
---- a/drivers/net/wireless/ipw2x00/ipw2100.c
-+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
-@@ -6068,7 +6068,7 @@ static struct net_device *ipw2100_alloc_
- priv->ieee->perfect_rssi = -20;
- priv->ieee->worst_rssi = -85;
-
-- dev->netdev_ops = &ipw2100_netdev_ops;
-+ netdev_attach_ops(dev, &ipw2100_netdev_ops);
- dev->ethtool_ops = &ipw2100_ethtool_ops;
- dev->wireless_handlers = &ipw2100_wx_handler_def;
- priv->wireless_data.libipw = priv->ieee;
+++ /dev/null
---- a/drivers/net/wireless/ipw2x00/ipw2200.c
-+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
-@@ -11681,7 +11681,7 @@ static int ipw_prom_alloc(struct ipw_pri
- memcpy(priv->prom_net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
-
- priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
-- priv->prom_net_dev->netdev_ops = &ipw_prom_netdev_ops;
-+ netdev_attach_ops(priv->prom_net_dev, &ipw_prom_netdev_ops);
-
- priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR;
- SET_NETDEV_DEV(priv->prom_net_dev, &priv->pci_dev->dev);
-@@ -11819,7 +11819,7 @@ static int ipw_pci_probe(struct pci_dev
- priv->ieee->perfect_rssi = -20;
- priv->ieee->worst_rssi = -85;
-
-- net_dev->netdev_ops = &ipw_netdev_ops;
-+ netdev_attach_ops(net_dev, &ipw_netdev_ops);
- priv->wireless_data.spy_data = &priv->ieee->spy_data;
- net_dev->wireless_data = &priv->wireless_data;
- net_dev->wireless_handlers = &ipw_wx_handler_def;
+++ /dev/null
---- a/drivers/net/wireless/libertas/main.c
-+++ b/drivers/net/wireless/libertas/main.c
-@@ -993,7 +993,7 @@ struct lbs_private *lbs_add_card(void *c
- wdev->netdev = dev;
- priv->dev = dev;
-
-- dev->netdev_ops = &lbs_netdev_ops;
-+ netdev_attach_ops(dev, &lbs_netdev_ops);
- dev->watchdog_timeo = 5 * HZ;
- dev->ethtool_ops = &lbs_ethtool_ops;
- dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
---- a/drivers/net/wireless/libertas/mesh.c
-+++ b/drivers/net/wireless/libertas/mesh.c
-@@ -1015,7 +1015,7 @@ static int lbs_add_mesh(struct lbs_priva
- mesh_dev->ieee80211_ptr = mesh_wdev;
- priv->mesh_dev = mesh_dev;
-
-- mesh_dev->netdev_ops = &mesh_netdev_ops;
-+ netdev_attach_ops(mesh_dev, &mesh_netdev_ops);
- mesh_dev->ethtool_ops = &lbs_ethtool_ops;
- eth_hw_addr_inherit(mesh_dev, priv->dev);
-
+++ /dev/null
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -1112,7 +1112,7 @@ static void ieee80211_if_setup(struct ne
- {
- ether_setup(dev);
- dev->priv_flags &= ~IFF_TX_SKB_SHARING;
-- dev->netdev_ops = &ieee80211_dataif_ops;
-+ netdev_attach_ops(dev, &ieee80211_dataif_ops);
- dev->destructor = free_netdev;
- }
-
-@@ -1275,7 +1275,7 @@ static void ieee80211_setup_sdata(struct
-
- /* only monitor/p2p-device differ */
- if (sdata->dev) {
-- sdata->dev->netdev_ops = &ieee80211_dataif_ops;
-+ netdev_attach_ops(sdata->dev, &ieee80211_dataif_ops);
- sdata->dev->type = ARPHRD_ETHER;
- }
-
-@@ -1317,7 +1317,7 @@ static void ieee80211_setup_sdata(struct
- break;
- case NL80211_IFTYPE_MONITOR:
- sdata->dev->type = ARPHRD_IEEE80211_RADIOTAP;
-- sdata->dev->netdev_ops = &ieee80211_monitorif_ops;
-+ netdev_attach_ops(sdata->dev, &ieee80211_monitorif_ops);
- sdata->u.mntr_flags = MONITOR_FLAG_CONTROL |
- MONITOR_FLAG_OTHER_BSS;
- break;
+++ /dev/null
---- a/drivers/net/wireless/mac80211_hwsim.c
-+++ b/drivers/net/wireless/mac80211_hwsim.c
-@@ -1761,7 +1761,7 @@ static const struct net_device_ops hwsim
-
- static void hwsim_mon_setup(struct net_device *dev)
- {
-- dev->netdev_ops = &hwsim_netdev_ops;
-+ netdev_attach_ops(dev, &hwsim_netdev_ops);
- dev->destructor = free_netdev;
- ether_setup(dev);
- dev->tx_queue_len = 0;
+++ /dev/null
---- a/drivers/net/wireless/mwifiex/main.c
-+++ b/drivers/net/wireless/mwifiex/main.c
-@@ -794,7 +794,7 @@ static const struct net_device_ops mwifi
- void mwifiex_init_priv_params(struct mwifiex_private *priv,
- struct net_device *dev)
- {
-- dev->netdev_ops = &mwifiex_netdev_ops;
-+ netdev_attach_ops(dev, &mwifiex_netdev_ops);
- dev->destructor = free_netdev;
- /* Initialize private structure */
- priv->current_key_index = 0;
+++ /dev/null
---- a/drivers/net/wireless/orinoco/main.c
-+++ b/drivers/net/wireless/orinoco/main.c
-@@ -2272,9 +2272,9 @@ int orinoco_if_add(struct orinoco_privat
- #endif
- /* Default to standard ops if not set */
- if (ops)
-- dev->netdev_ops = ops;
-+ netdev_attach_ops(dev, ops);
- else
-- dev->netdev_ops = &orinoco_netdev_ops;
-+ netdev_attach_ops(dev, &orinoco_netdev_ops);
-
- /* we use the default eth_mac_addr for setting the MAC addr */
-
+++ /dev/null
---- a/drivers/net/usb/qmi_wwan.c
-+++ b/drivers/net/usb/qmi_wwan.c
-@@ -343,7 +343,7 @@ next_desc:
- dev->net->dev_addr[0] |= 0x02; /* set local assignment bit */
- dev->net->dev_addr[0] &= 0xbf; /* clear "IP" bit */
- }
-- dev->net->netdev_ops = &qmi_wwan_netdev_ops;
-+ netdev_attach_ops(dev->net, &qmi_wwan_netdev_ops);
- err:
- return status;
- }
+++ /dev/null
---- a/drivers/net/usb/rndis_host.c
-+++ b/drivers/net/usb/rndis_host.c
-@@ -358,7 +358,7 @@ generic_rndis_bind(struct usbnet *dev, s
- dev->rx_urb_size &= ~(dev->maxpacket - 1);
- u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size);
-
-- net->netdev_ops = &rndis_netdev_ops;
-+ netdev_attach_ops(net, &rndis_netdev_ops);
-
- retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
- if (unlikely(retval < 0)) {
+++ /dev/null
---- a/drivers/net/wireless/rndis_wlan.c
-+++ b/drivers/net/wireless/rndis_wlan.c
-@@ -3438,7 +3438,7 @@ static int rndis_wlan_bind(struct usbnet
- * rndis_host wants to avoid all OID as much as possible
- * so do promisc/multicast handling in rndis_wlan.
- */
-- usbdev->net->netdev_ops = &rndis_wlan_netdev_ops;
-+ netdev_attach_ops(usbdev->net, &rndis_wlan_netdev_ops);
-
- tmp = cpu_to_le32(RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST);
- retval = rndis_set_oid(usbdev,
+++ /dev/null
---- a/drivers/net/usb/sierra_net.c
-+++ b/drivers/net/usb/sierra_net.c
-@@ -695,7 +695,7 @@ static int sierra_net_bind(struct usbnet
-
- priv->usbnet = dev;
- priv->ifnum = ifacenum;
-- dev->net->netdev_ops = &sierra_net_device_ops;
-+ netdev_attach_ops(dev->net, &sierra_net_device_ops);
-
- /* change MAC addr to include, ifacenum, and to be unique */
- dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter);
+++ /dev/null
---- a/drivers/net/usb/usbnet.c
-+++ b/drivers/net/usb/usbnet.c
-@@ -1619,7 +1619,7 @@ usbnet_probe (struct usb_interface *udev
- net->features |= NETIF_F_HIGHDMA;
- #endif
-
-- net->netdev_ops = &usbnet_netdev_ops;
-+ netdev_attach_ops(net, &usbnet_netdev_ops);
- net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
- net->ethtool_ops = &usbnet_ethtool_ops;
-
+++ /dev/null
---- a/net/wireless/wext-core.c
-+++ b/net/wireless/wext-core.c
-@@ -925,9 +925,7 @@ static int wireless_process_ioctl(struct
- return private(dev, iwr, cmd, info, handler);
- }
- /* Old driver API : call driver ioctl handler */
-- if (dev->netdev_ops->ndo_do_ioctl)
-- return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd);
-- return -EOPNOTSUPP;
-+ return ndo_do_ioctl(dev, ifr, cmd);
- }
-
- /* If command is `set a parameter', or `get the encoding parameters',
+++ /dev/null
---- a/drivers/net/wireless/ath/wil6210/netdev.c
-+++ b/drivers/net/wireless/ath/wil6210/netdev.c
-@@ -125,7 +125,7 @@ void *wil_if_alloc(struct device *dev, v
- goto out_priv;
- }
-
-- ndev->netdev_ops = &wil_netdev_ops;
-+ netdev_attach_ops(ndev, &wil_netdev_ops);
- ndev->ieee80211_ptr = wdev;
- ndev->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
- ndev->features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM;