Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
ndo_change_carrier [2018/08/04 12:09] – [Overview] rpjdayndo_change_carrier [2018/08/04 17:31] (current) – [Overview] rpjday
Line 1: Line 1:
 ===== Overview ===== ===== Overview =====
  
-Setting/detecting carrier, and the implications of setting ''net_device_ops'' ''ndo_change_carrier'' field.+Setting/detecting carrier, and the subsequent implications of setting ''net_device_ops'' ''ndo_change_carrier'' field (if any implications actually exist):
  
-===== include/linux/netdevice.h =====+===== Normal behaviour ===== 
 + 
 +==== Net device state ==== 
 + 
 +From ''include/linux/netdevice.h'': 
 + 
 +Net device state:
  
 <code> <code>
 struct net_device { struct net_device {
         ... snip ...         ... snip ...
-        const struct net_device_ops *netdev_ops;+        unsigned long           state;
         ... snip ...         ... snip ...
 </code> </code>
 +
 +State flag bits for later testing:
  
 <code> <code>
-struct net_device_ops {+enum netdev_state_t { 
 +        __LINK_STATE_START, 
 +        __LINK_STATE_PRESENT, 
 +        __LINK_STATE_NOCARRIER, 
 +        __LINK_STATE_LINKWATCH_PENDING, 
 +        __LINK_STATE_DORMANT, 
 +}; 
 +</code>
  
-... snip ...+==== Checking for state of carrier ====
  
-* int (*ndo_change_carrier)(struct net_device *dev, bool new_carrier); +Again from ''netdevice.h'': 
-      Called to change device carrierSoft-devices (like dummy, team, etc) + 
- *      which do not represent real hardware may define this to allow their +<code> 
-      userspace components to manage their virtual carrier state. Devices +/*
-      that determine carrier state from physical hardware properties (eg +      netif_carrier_ok - test if carrier present 
-      network cables) or protocol-dependent mechanisms (eg +      @dev: network device
-      USB_CDC_NOTIFY_NETWORK_CONNECTION) should NOT implement this function.+
  *  *
 + * Check if carrier is present on device
 + */
 +static inline bool netif_carrier_ok(const struct net_device *dev)
 +{
 +        return !test_bit(__LINK_STATE_NOCARRIER, &dev->state);
 +}
 +
 +void netif_carrier_on(struct net_device *dev);
 +void netif_carrier_off(struct net_device *dev);
 </code> </code>
-===== net/core/net-sysfs.c =====+ 
 +==== Test for interface running ==== 
 + 
 +Still in ''netdevice.h'':
  
 <code> <code>
-static int change_carrier(struct net_device *dev, unsigned long new_carrier)+/** 
 + * netif_running - test if up 
 + * @dev: network device 
 + * 
 + * Test if the device has been brought up. 
 + */ 
 +static inline bool netif_running(const struct net_device *dev)
 { {
-        if (!netif_running(dev)) + return test_bit(__LINK_STATE_START, &dev->state);
-                return -EINVAL; +
-        return dev_change_carrier(dev, (bool) new_carrier);+
 } }
 +</code>
 +==== Test if carrier on or off ====
  
-static ssize_t carrier_store(struct device *dev, struct device_attribute *attr, +From ''net/sched/sch_generic.c'': 
-                             const char *buf, size_t len)+ 
 +<code> 
 +/*
 +      netif_carrier_on - set carrier 
 +      @dev: network device 
 + 
 + Device has detected that carrier. 
 + */ 
 +void netif_carrier_on(struct net_device *dev)
 { {
-        return netdev_store(dev, attr, buf, len, change_carrier);+        if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state)) { 
 +                if (dev->reg_state == NETREG_UNINITIALIZED) 
 +                        return
 +                atomic_inc(&dev->carrier_up_count); 
 +                linkwatch_fire_event(dev); 
 +                if (netif_running(dev)) 
 +                        __netdev_watchdog_up(dev); 
 +        }
 } }
 +EXPORT_SYMBOL(netif_carrier_on);
  
-static ssize_t carrier_show(struct device *dev, +/*
-                            struct device_attribute *attr, char *buf)+      netif_carrier_off - clear carrier 
 +      @dev: network device 
 + * 
 + Device has detected loss of carrier. 
 + */ 
 +void netif_carrier_off(struct net_device *dev)
 { {
-        struct net_device *netdev = to_net_dev(dev); +        if (!test_and_set_bit(__LINK_STATE_NOCARRIER, &dev->state)) { 
-        if (netif_running(netdev)) { +                if (dev->reg_state == NETREG_UNINITIALIZED) 
-                return sprintf(buf, fmt_dec, !!netif_carrier_ok(netdev));+                        return
 +                atomic_inc(&dev->carrier_down_count)
 +                linkwatch_fire_event(dev);
         }         }
-        return -EINVAL; 
 } }
-static DEVICE_ATTR_RW(carrier);+EXPORT_SYMBOL(netif_carrier_off);
 </code> </code>
- 
-Note how showing the value of ''carrier'' involves calling: 
- 
-  * ''if (netif_running(netdev))'' 
-  * ''!!netif_carrier_ok(netdev)'' 
  • ndo_change_carrier.1533384548.txt.gz
  • Last modified: 2018/08/04 12:09
  • by rpjday