diff options
author | Stephen Hemminger <shemminger@vyatta.com> | 2008-11-20 00:32:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-20 00:32:24 -0500 |
commit | d314774cf2cd5dfeb39a00d37deee65d4c627927 (patch) | |
tree | 1c7778b509cea814aa2b7115949667941037d07c /net/core | |
parent | 6b41e7dd90c6a628ab5fb8d781302d60a243b2ce (diff) |
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>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 109 | ||||
-rw-r--r-- | net/core/netpoll.c | 7 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 9 |
3 files changed, 86 insertions, 39 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index e08c0fcd603b..ca14ab407b33 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1059,6 +1059,7 @@ void dev_load(struct net *net, const char *name) | |||
1059 | */ | 1059 | */ |
1060 | int dev_open(struct net_device *dev) | 1060 | int dev_open(struct net_device *dev) |
1061 | { | 1061 | { |
1062 | const struct net_device_ops *ops = dev->netdev_ops; | ||
1062 | int ret = 0; | 1063 | int ret = 0; |
1063 | 1064 | ||
1064 | ASSERT_RTNL(); | 1065 | ASSERT_RTNL(); |
@@ -1081,11 +1082,11 @@ int dev_open(struct net_device *dev) | |||
1081 | */ | 1082 | */ |
1082 | set_bit(__LINK_STATE_START, &dev->state); | 1083 | set_bit(__LINK_STATE_START, &dev->state); |
1083 | 1084 | ||
1084 | if (dev->validate_addr) | 1085 | if (ops->ndo_validate_addr) |
1085 | ret = dev->validate_addr(dev); | 1086 | ret = ops->ndo_validate_addr(dev); |
1086 | 1087 | ||
1087 | if (!ret && dev->open) | 1088 | if (!ret && ops->ndo_open) |
1088 | ret = dev->open(dev); | 1089 | ret = ops->ndo_open(dev); |
1089 | 1090 | ||
1090 | /* | 1091 | /* |
1091 | * If it went open OK then: | 1092 | * If it went open OK then: |
@@ -1129,6 +1130,7 @@ int dev_open(struct net_device *dev) | |||
1129 | */ | 1130 | */ |
1130 | int dev_close(struct net_device *dev) | 1131 | int dev_close(struct net_device *dev) |
1131 | { | 1132 | { |
1133 | const struct net_device_ops *ops = dev->netdev_ops; | ||
1132 | ASSERT_RTNL(); | 1134 | ASSERT_RTNL(); |
1133 | 1135 | ||
1134 | might_sleep(); | 1136 | might_sleep(); |
@@ -1161,8 +1163,8 @@ int dev_close(struct net_device *dev) | |||
1161 | * We allow it to be called even after a DETACH hot-plug | 1163 | * We allow it to be called even after a DETACH hot-plug |
1162 | * event. | 1164 | * event. |
1163 | */ | 1165 | */ |
1164 | if (dev->stop) | 1166 | if (ops->ndo_stop) |
1165 | dev->stop(dev); | 1167 | ops->ndo_stop(dev); |
1166 | 1168 | ||
1167 | /* | 1169 | /* |
1168 | * Device is now down. | 1170 | * Device is now down. |
@@ -2930,8 +2932,10 @@ int netdev_set_master(struct net_device *slave, struct net_device *master) | |||
2930 | 2932 | ||
2931 | static void dev_change_rx_flags(struct net_device *dev, int flags) | 2933 | static void dev_change_rx_flags(struct net_device *dev, int flags) |
2932 | { | 2934 | { |
2933 | if (dev->flags & IFF_UP && dev->change_rx_flags) | 2935 | const struct net_device_ops *ops = dev->netdev_ops; |
2934 | dev->change_rx_flags(dev, flags); | 2936 | |
2937 | if ((dev->flags & IFF_UP) && ops->ndo_change_rx_flags) | ||
2938 | ops->ndo_change_rx_flags(dev, flags); | ||
2935 | } | 2939 | } |
2936 | 2940 | ||
2937 | static int __dev_set_promiscuity(struct net_device *dev, int inc) | 2941 | static int __dev_set_promiscuity(struct net_device *dev, int inc) |
@@ -3051,6 +3055,8 @@ int dev_set_allmulti(struct net_device *dev, int inc) | |||
3051 | */ | 3055 | */ |
3052 | void __dev_set_rx_mode(struct net_device *dev) | 3056 | void __dev_set_rx_mode(struct net_device *dev) |
3053 | { | 3057 | { |
3058 | const struct net_device_ops *ops = dev->netdev_ops; | ||
3059 | |||
3054 | /* dev_open will call this function so the list will stay sane. */ | 3060 | /* dev_open will call this function so the list will stay sane. */ |
3055 | if (!(dev->flags&IFF_UP)) | 3061 | if (!(dev->flags&IFF_UP)) |
3056 | return; | 3062 | return; |
@@ -3058,8 +3064,8 @@ void __dev_set_rx_mode(struct net_device *dev) | |||
3058 | if (!netif_device_present(dev)) | 3064 | if (!netif_device_present(dev)) |
3059 | return; | 3065 | return; |
3060 | 3066 | ||
3061 | if (dev->set_rx_mode) | 3067 | if (ops->ndo_set_rx_mode) |
3062 | dev->set_rx_mode(dev); | 3068 | ops->ndo_set_rx_mode(dev); |
3063 | else { | 3069 | else { |
3064 | /* Unicast addresses changes may only happen under the rtnl, | 3070 | /* Unicast addresses changes may only happen under the rtnl, |
3065 | * therefore calling __dev_set_promiscuity here is safe. | 3071 | * therefore calling __dev_set_promiscuity here is safe. |
@@ -3072,8 +3078,8 @@ void __dev_set_rx_mode(struct net_device *dev) | |||
3072 | dev->uc_promisc = 0; | 3078 | dev->uc_promisc = 0; |
3073 | } | 3079 | } |
3074 | 3080 | ||
3075 | if (dev->set_multicast_list) | 3081 | if (ops->ndo_set_multicast_list) |
3076 | dev->set_multicast_list(dev); | 3082 | ops->ndo_set_multicast_list(dev); |
3077 | } | 3083 | } |
3078 | } | 3084 | } |
3079 | 3085 | ||
@@ -3432,6 +3438,7 @@ int dev_change_flags(struct net_device *dev, unsigned flags) | |||
3432 | */ | 3438 | */ |
3433 | int dev_set_mtu(struct net_device *dev, int new_mtu) | 3439 | int dev_set_mtu(struct net_device *dev, int new_mtu) |
3434 | { | 3440 | { |
3441 | const struct net_device_ops *ops = dev->netdev_ops; | ||
3435 | int err; | 3442 | int err; |
3436 | 3443 | ||
3437 | if (new_mtu == dev->mtu) | 3444 | if (new_mtu == dev->mtu) |
@@ -3445,10 +3452,11 @@ int dev_set_mtu(struct net_device *dev, int new_mtu) | |||
3445 | return -ENODEV; | 3452 | return -ENODEV; |
3446 | 3453 | ||
3447 | err = 0; | 3454 | err = 0; |
3448 | if (dev->change_mtu) | 3455 | if (ops->ndo_change_mtu) |
3449 | err = dev->change_mtu(dev, new_mtu); | 3456 | err = ops->ndo_change_mtu(dev, new_mtu); |
3450 | else | 3457 | else |
3451 | dev->mtu = new_mtu; | 3458 | dev->mtu = new_mtu; |
3459 | |||
3452 | if (!err && dev->flags & IFF_UP) | 3460 | if (!err && dev->flags & IFF_UP) |
3453 | call_netdevice_notifiers(NETDEV_CHANGEMTU, dev); | 3461 | call_netdevice_notifiers(NETDEV_CHANGEMTU, dev); |
3454 | return err; | 3462 | return err; |
@@ -3463,15 +3471,16 @@ int dev_set_mtu(struct net_device *dev, int new_mtu) | |||
3463 | */ | 3471 | */ |
3464 | int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) | 3472 | int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) |
3465 | { | 3473 | { |
3474 | const struct net_device_ops *ops = dev->netdev_ops; | ||
3466 | int err; | 3475 | int err; |
3467 | 3476 | ||
3468 | if (!dev->set_mac_address) | 3477 | if (!ops->ndo_set_mac_address) |
3469 | return -EOPNOTSUPP; | 3478 | return -EOPNOTSUPP; |
3470 | if (sa->sa_family != dev->type) | 3479 | if (sa->sa_family != dev->type) |
3471 | return -EINVAL; | 3480 | return -EINVAL; |
3472 | if (!netif_device_present(dev)) | 3481 | if (!netif_device_present(dev)) |
3473 | return -ENODEV; | 3482 | return -ENODEV; |
3474 | err = dev->set_mac_address(dev, sa); | 3483 | err = ops->ndo_set_mac_address(dev, sa); |
3475 | if (!err) | 3484 | if (!err) |
3476 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 3485 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); |
3477 | return err; | 3486 | return err; |
@@ -3551,6 +3560,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) | |||
3551 | { | 3560 | { |
3552 | int err; | 3561 | int err; |
3553 | struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name); | 3562 | struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name); |
3563 | const struct net_device_ops *ops = dev->netdev_ops; | ||
3554 | 3564 | ||
3555 | if (!dev) | 3565 | if (!dev) |
3556 | return -ENODEV; | 3566 | return -ENODEV; |
@@ -3578,15 +3588,15 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) | |||
3578 | return 0; | 3588 | return 0; |
3579 | 3589 | ||
3580 | case SIOCSIFMAP: | 3590 | case SIOCSIFMAP: |
3581 | if (dev->set_config) { | 3591 | if (ops->ndo_set_config) { |
3582 | if (!netif_device_present(dev)) | 3592 | if (!netif_device_present(dev)) |
3583 | return -ENODEV; | 3593 | return -ENODEV; |
3584 | return dev->set_config(dev, &ifr->ifr_map); | 3594 | return ops->ndo_set_config(dev, &ifr->ifr_map); |
3585 | } | 3595 | } |
3586 | return -EOPNOTSUPP; | 3596 | return -EOPNOTSUPP; |
3587 | 3597 | ||
3588 | case SIOCADDMULTI: | 3598 | case SIOCADDMULTI: |
3589 | if ((!dev->set_multicast_list && !dev->set_rx_mode) || | 3599 | if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) || |
3590 | ifr->ifr_hwaddr.sa_family != AF_UNSPEC) | 3600 | ifr->ifr_hwaddr.sa_family != AF_UNSPEC) |
3591 | return -EINVAL; | 3601 | return -EINVAL; |
3592 | if (!netif_device_present(dev)) | 3602 | if (!netif_device_present(dev)) |
@@ -3595,7 +3605,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) | |||
3595 | dev->addr_len, 1); | 3605 | dev->addr_len, 1); |
3596 | 3606 | ||
3597 | case SIOCDELMULTI: | 3607 | case SIOCDELMULTI: |
3598 | if ((!dev->set_multicast_list && !dev->set_rx_mode) || | 3608 | if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) || |
3599 | ifr->ifr_hwaddr.sa_family != AF_UNSPEC) | 3609 | ifr->ifr_hwaddr.sa_family != AF_UNSPEC) |
3600 | return -EINVAL; | 3610 | return -EINVAL; |
3601 | if (!netif_device_present(dev)) | 3611 | if (!netif_device_present(dev)) |
@@ -3633,10 +3643,9 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) | |||
3633 | cmd == SIOCBRDELIF || | 3643 | cmd == SIOCBRDELIF || |
3634 | cmd == SIOCWANDEV) { | 3644 | cmd == SIOCWANDEV) { |
3635 | err = -EOPNOTSUPP; | 3645 | err = -EOPNOTSUPP; |
3636 | if (dev->do_ioctl) { | 3646 | if (ops->ndo_do_ioctl) { |
3637 | if (netif_device_present(dev)) | 3647 | if (netif_device_present(dev)) |
3638 | err = dev->do_ioctl(dev, ifr, | 3648 | err = ops->ndo_do_ioctl(dev, ifr, cmd); |
3639 | cmd); | ||
3640 | else | 3649 | else |
3641 | err = -ENODEV; | 3650 | err = -ENODEV; |
3642 | } | 3651 | } |
@@ -3897,8 +3906,8 @@ static void rollback_registered(struct net_device *dev) | |||
3897 | */ | 3906 | */ |
3898 | dev_addr_discard(dev); | 3907 | dev_addr_discard(dev); |
3899 | 3908 | ||
3900 | if (dev->uninit) | 3909 | if (dev->netdev_ops->ndo_uninit) |
3901 | dev->uninit(dev); | 3910 | dev->netdev_ops->ndo_uninit(dev); |
3902 | 3911 | ||
3903 | /* Notifier chain MUST detach us from master device. */ | 3912 | /* Notifier chain MUST detach us from master device. */ |
3904 | WARN_ON(dev->master); | 3913 | WARN_ON(dev->master); |
@@ -3988,7 +3997,7 @@ int register_netdevice(struct net_device *dev) | |||
3988 | struct hlist_head *head; | 3997 | struct hlist_head *head; |
3989 | struct hlist_node *p; | 3998 | struct hlist_node *p; |
3990 | int ret; | 3999 | int ret; |
3991 | struct net *net; | 4000 | struct net *net = dev_net(dev); |
3992 | 4001 | ||
3993 | BUG_ON(dev_boot_phase); | 4002 | BUG_ON(dev_boot_phase); |
3994 | ASSERT_RTNL(); | 4003 | ASSERT_RTNL(); |
@@ -3997,8 +4006,7 @@ int register_netdevice(struct net_device *dev) | |||
3997 | 4006 | ||
3998 | /* When net_device's are persistent, this will be fatal. */ | 4007 | /* When net_device's are persistent, this will be fatal. */ |
3999 | BUG_ON(dev->reg_state != NETREG_UNINITIALIZED); | 4008 | BUG_ON(dev->reg_state != NETREG_UNINITIALIZED); |
4000 | BUG_ON(!dev_net(dev)); | 4009 | BUG_ON(!net); |
4001 | net = dev_net(dev); | ||
4002 | 4010 | ||
4003 | spin_lock_init(&dev->addr_list_lock); | 4011 | spin_lock_init(&dev->addr_list_lock); |
4004 | netdev_set_addr_lockdep_class(dev); | 4012 | netdev_set_addr_lockdep_class(dev); |
@@ -4006,9 +4014,46 @@ int register_netdevice(struct net_device *dev) | |||
4006 | 4014 | ||
4007 | dev->iflink = -1; | 4015 | dev->iflink = -1; |
4008 | 4016 | ||
4017 | #ifdef CONFIG_COMPAT_NET_DEV_OPS | ||
4018 | /* Netdevice_ops API compatiability support. | ||
4019 | * This is temporary until all network devices are converted. | ||
4020 | */ | ||
4021 | if (dev->netdev_ops) { | ||
4022 | const struct net_device_ops *ops = dev->netdev_ops; | ||
4023 | |||
4024 | dev->init = ops->ndo_init; | ||
4025 | dev->uninit = ops->ndo_uninit; | ||
4026 | dev->open = ops->ndo_open; | ||
4027 | dev->change_rx_flags = ops->ndo_change_rx_flags; | ||
4028 | dev->set_rx_mode = ops->ndo_set_rx_mode; | ||
4029 | dev->set_multicast_list = ops->ndo_set_multicast_list; | ||
4030 | dev->set_mac_address = ops->ndo_set_mac_address; | ||
4031 | dev->validate_addr = ops->ndo_validate_addr; | ||
4032 | dev->do_ioctl = ops->ndo_do_ioctl; | ||
4033 | dev->set_config = ops->ndo_set_config; | ||
4034 | dev->change_mtu = ops->ndo_change_mtu; | ||
4035 | dev->tx_timeout = ops->ndo_tx_timeout; | ||
4036 | dev->get_stats = ops->ndo_get_stats; | ||
4037 | dev->vlan_rx_register = ops->ndo_vlan_rx_register; | ||
4038 | dev->vlan_rx_add_vid = ops->ndo_vlan_rx_add_vid; | ||
4039 | dev->vlan_rx_kill_vid = ops->ndo_vlan_rx_kill_vid; | ||
4040 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
4041 | dev->poll_controller = ops->ndo_poll_controller; | ||
4042 | #endif | ||
4043 | } else { | ||
4044 | char drivername[64]; | ||
4045 | pr_info("%s (%s): not using net_device_ops yet\n", | ||
4046 | dev->name, netdev_drivername(dev, drivername, 64)); | ||
4047 | |||
4048 | /* This works only because net_device_ops and the | ||
4049 | compatiablity structure are the same. */ | ||
4050 | dev->netdev_ops = (void *) &(dev->init); | ||
4051 | } | ||
4052 | #endif | ||
4053 | |||
4009 | /* Init, if this function is available */ | 4054 | /* Init, if this function is available */ |
4010 | if (dev->init) { | 4055 | if (dev->netdev_ops->ndo_init) { |
4011 | ret = dev->init(dev); | 4056 | ret = dev->netdev_ops->ndo_init(dev); |
4012 | if (ret) { | 4057 | if (ret) { |
4013 | if (ret > 0) | 4058 | if (ret > 0) |
4014 | ret = -EIO; | 4059 | ret = -EIO; |
@@ -4086,8 +4131,8 @@ out: | |||
4086 | return ret; | 4131 | return ret; |
4087 | 4132 | ||
4088 | err_uninit: | 4133 | err_uninit: |
4089 | if (dev->uninit) | 4134 | if (dev->netdev_ops->ndo_uninit) |
4090 | dev->uninit(dev); | 4135 | dev->netdev_ops->ndo_uninit(dev); |
4091 | goto out; | 4136 | goto out; |
4092 | } | 4137 | } |
4093 | 4138 | ||
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index fc4e28e23b89..630df6034444 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -172,12 +172,13 @@ static void service_arp_queue(struct netpoll_info *npi) | |||
172 | void netpoll_poll(struct netpoll *np) | 172 | void netpoll_poll(struct netpoll *np) |
173 | { | 173 | { |
174 | struct net_device *dev = np->dev; | 174 | struct net_device *dev = np->dev; |
175 | const struct net_device_ops *ops = dev->netdev_ops; | ||
175 | 176 | ||
176 | if (!dev || !netif_running(dev) || !dev->poll_controller) | 177 | if (!dev || !netif_running(dev) || !ops->ndo_poll_controller) |
177 | return; | 178 | return; |
178 | 179 | ||
179 | /* Process pending work on NIC */ | 180 | /* Process pending work on NIC */ |
180 | dev->poll_controller(dev); | 181 | ops->ndo_poll_controller(dev); |
181 | 182 | ||
182 | poll_napi(dev); | 183 | poll_napi(dev); |
183 | 184 | ||
@@ -694,7 +695,7 @@ int netpoll_setup(struct netpoll *np) | |||
694 | atomic_inc(&npinfo->refcnt); | 695 | atomic_inc(&npinfo->refcnt); |
695 | } | 696 | } |
696 | 697 | ||
697 | if (!ndev->poll_controller) { | 698 | if (!ndev->netdev_ops->ndo_poll_controller) { |
698 | printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n", | 699 | printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n", |
699 | np->name, np->dev_name); | 700 | np->name, np->dev_name); |
700 | err = -ENOTSUPP; | 701 | err = -ENOTSUPP; |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 4dfb6b4d4559..6f8e0778e565 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -762,6 +762,7 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[]) | |||
762 | static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | 762 | static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, |
763 | struct nlattr **tb, char *ifname, int modified) | 763 | struct nlattr **tb, char *ifname, int modified) |
764 | { | 764 | { |
765 | const struct net_device_ops *ops = dev->netdev_ops; | ||
765 | int send_addr_notify = 0; | 766 | int send_addr_notify = 0; |
766 | int err; | 767 | int err; |
767 | 768 | ||
@@ -783,7 +784,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
783 | struct rtnl_link_ifmap *u_map; | 784 | struct rtnl_link_ifmap *u_map; |
784 | struct ifmap k_map; | 785 | struct ifmap k_map; |
785 | 786 | ||
786 | if (!dev->set_config) { | 787 | if (!ops->ndo_set_config) { |
787 | err = -EOPNOTSUPP; | 788 | err = -EOPNOTSUPP; |
788 | goto errout; | 789 | goto errout; |
789 | } | 790 | } |
@@ -801,7 +802,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
801 | k_map.dma = (unsigned char) u_map->dma; | 802 | k_map.dma = (unsigned char) u_map->dma; |
802 | k_map.port = (unsigned char) u_map->port; | 803 | k_map.port = (unsigned char) u_map->port; |
803 | 804 | ||
804 | err = dev->set_config(dev, &k_map); | 805 | err = ops->ndo_set_config(dev, &k_map); |
805 | if (err < 0) | 806 | if (err < 0) |
806 | goto errout; | 807 | goto errout; |
807 | 808 | ||
@@ -812,7 +813,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
812 | struct sockaddr *sa; | 813 | struct sockaddr *sa; |
813 | int len; | 814 | int len; |
814 | 815 | ||
815 | if (!dev->set_mac_address) { | 816 | if (!ops->ndo_set_mac_address) { |
816 | err = -EOPNOTSUPP; | 817 | err = -EOPNOTSUPP; |
817 | goto errout; | 818 | goto errout; |
818 | } | 819 | } |
@@ -831,7 +832,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
831 | sa->sa_family = dev->type; | 832 | sa->sa_family = dev->type; |
832 | memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]), | 833 | memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]), |
833 | dev->addr_len); | 834 | dev->addr_len); |
834 | err = dev->set_mac_address(dev, sa); | 835 | err = ops->ndo_set_mac_address(dev, sa); |
835 | kfree(sa); | 836 | kfree(sa); |
836 | if (err) | 837 | if (err) |
837 | goto errout; | 838 | goto errout; |