diff options
| author | David S. Miller <davem@davemloft.net> | 2008-08-07 02:10:27 -0700 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2008-08-07 02:10:27 -0700 | 
| commit | 32bb93b02da8c75031e601ff1f9a25f99febbe5f (patch) | |
| tree | 429d2b978f517d366de572fa5058d513ed7b51a6 /drivers/net/e1000e/netdev.c | |
| parent | 6edafaaf6f5e70ef1e620ff01bd6bacebe1e0718 (diff) | |
| parent | 3859069bc3358772b08bd91efe9edec39a746ea8 (diff) | |
Merge branch 'upstream-davem' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
Diffstat (limited to 'drivers/net/e1000e/netdev.c')
| -rw-r--r-- | drivers/net/e1000e/netdev.c | 246 | 
1 files changed, 110 insertions, 136 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index d1367789976..05b0b2f9c54 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -484,8 +484,8 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,  		 * packet, also make sure the frame isn't just CRC only */  		if (!(status & E1000_RXD_STAT_EOP) || (length <= 4)) {  			/* All receives must fit into a single buffer */ -			ndev_dbg(netdev, "%s: Receive packet consumed " -				 "multiple buffers\n", netdev->name); +			e_dbg("%s: Receive packet consumed multiple buffers\n", +			      netdev->name);  			/* recycle */  			buffer_info->skb = skb;  			goto next_desc; @@ -576,28 +576,26 @@ static void e1000_print_tx_hang(struct e1000_adapter *adapter)  	unsigned int i = tx_ring->next_to_clean;  	unsigned int eop = tx_ring->buffer_info[i].next_to_watch;  	struct e1000_tx_desc *eop_desc = E1000_TX_DESC(*tx_ring, eop); -	struct net_device *netdev = adapter->netdev;  	/* detected Tx unit hang */ -	ndev_err(netdev, -		 "Detected Tx Unit Hang:\n" -		 "  TDH                  <%x>\n" -		 "  TDT                  <%x>\n" -		 "  next_to_use          <%x>\n" -		 "  next_to_clean        <%x>\n" -		 "buffer_info[next_to_clean]:\n" -		 "  time_stamp           <%lx>\n" -		 "  next_to_watch        <%x>\n" -		 "  jiffies              <%lx>\n" -		 "  next_to_watch.status <%x>\n", -		 readl(adapter->hw.hw_addr + tx_ring->head), -		 readl(adapter->hw.hw_addr + tx_ring->tail), -		 tx_ring->next_to_use, -		 tx_ring->next_to_clean, -		 tx_ring->buffer_info[eop].time_stamp, -		 eop, -		 jiffies, -		 eop_desc->upper.fields.status); +	e_err("Detected Tx Unit Hang:\n" +	      "  TDH                  <%x>\n" +	      "  TDT                  <%x>\n" +	      "  next_to_use          <%x>\n" +	      "  next_to_clean        <%x>\n" +	      "buffer_info[next_to_clean]:\n" +	      "  time_stamp           <%lx>\n" +	      "  next_to_watch        <%x>\n" +	      "  jiffies              <%lx>\n" +	      "  next_to_watch.status <%x>\n", +	      readl(adapter->hw.hw_addr + tx_ring->head), +	      readl(adapter->hw.hw_addr + tx_ring->tail), +	      tx_ring->next_to_use, +	      tx_ring->next_to_clean, +	      tx_ring->buffer_info[eop].time_stamp, +	      eop, +	      jiffies, +	      eop_desc->upper.fields.status);  }  /** @@ -747,8 +745,8 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,  		buffer_info->dma = 0;  		if (!(staterr & E1000_RXD_STAT_EOP)) { -			ndev_dbg(netdev, "%s: Packet Split buffers didn't pick " -				 "up the full packet\n", netdev->name); +			e_dbg("%s: Packet Split buffers didn't pick up the " +			      "full packet\n", netdev->name);  			dev_kfree_skb_irq(skb);  			goto next_desc;  		} @@ -761,8 +759,8 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,  		length = le16_to_cpu(rx_desc->wb.middle.length0);  		if (!length) { -			ndev_dbg(netdev, "%s: Last part of the packet spanning" -				 " multiple descriptors\n", netdev->name); +			e_dbg("%s: Last part of the packet spanning multiple " +			      "descriptors\n", netdev->name);  			dev_kfree_skb_irq(skb);  			goto next_desc;  		} @@ -1011,7 +1009,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,  		/* eth type trans needs skb->data to point to something */  		if (!pskb_may_pull(skb, ETH_HLEN)) { -			ndev_err(netdev, "pskb_may_pull failed.\n"); +			e_err("pskb_may_pull failed.\n");  			dev_kfree_skb(skb);  			goto next_desc;  		} @@ -1251,10 +1249,8 @@ static int e1000_request_irq(struct e1000_adapter *adapter)  	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,  			  netdev);  	if (err) { -		ndev_err(netdev, -		       "Unable to allocate %s interrupt (return: %d)\n", -			adapter->flags & FLAG_MSI_ENABLED ? "MSI":"INTx", -			err); +		e_err("Unable to allocate %s interrupt (return: %d)\n", +		      adapter->flags & FLAG_MSI_ENABLED ? "MSI":"INTx",	err);  		if (adapter->flags & FLAG_MSI_ENABLED)  			pci_disable_msi(adapter->pdev);  	} @@ -1395,8 +1391,7 @@ int e1000e_setup_tx_resources(struct e1000_adapter *adapter)  	return 0;  err:  	vfree(tx_ring->buffer_info); -	ndev_err(adapter->netdev, -	"Unable to allocate memory for the transmit descriptor ring\n"); +	e_err("Unable to allocate memory for the transmit descriptor ring\n");  	return err;  } @@ -1450,8 +1445,7 @@ err_pages:  	}  err:  	vfree(rx_ring->buffer_info); -	ndev_err(adapter->netdev, -	"Unable to allocate memory for the transmit descriptor ring\n"); +	e_err("Unable to allocate memory for the transmit descriptor ring\n");  	return err;  } @@ -2450,13 +2444,13 @@ void e1000e_reset(struct e1000_adapter *adapter)  	 * For parts with AMT enabled, let the firmware know  	 * that the network interface is in control  	 */ -	if ((adapter->flags & FLAG_HAS_AMT) && e1000e_check_mng_mode(hw)) +	if (adapter->flags & FLAG_HAS_AMT)  		e1000_get_hw_control(adapter);  	ew32(WUC, 0);  	if (mac->ops.init_hw(hw)) -		ndev_err(adapter->netdev, "Hardware Error\n"); +		e_err("Hardware Error\n");  	e1000_update_mng_vlan(adapter); @@ -2591,7 +2585,7 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter)  	return 0;  err: -	ndev_err(netdev, "Unable to allocate memory for queues\n"); +	e_err("Unable to allocate memory for queues\n");  	kfree(adapter->rx_ring);  	kfree(adapter->tx_ring);  	return -ENOMEM; @@ -2640,8 +2634,7 @@ static int e1000_open(struct net_device *netdev)  	 * If AMT is enabled, let the firmware know that the network  	 * interface is now open  	 */ -	if ((adapter->flags & FLAG_HAS_AMT) && -	    e1000e_check_mng_mode(&adapter->hw)) +	if (adapter->flags & FLAG_HAS_AMT)  		e1000_get_hw_control(adapter);  	/* @@ -2719,8 +2712,7 @@ static int e1000_close(struct net_device *netdev)  	 * If AMT is enabled, let the firmware know that the network  	 * interface is now closed  	 */ -	if ((adapter->flags & FLAG_HAS_AMT) && -	    e1000e_check_mng_mode(&adapter->hw)) +	if (adapter->flags & FLAG_HAS_AMT)  		e1000_release_hw_control(adapter);  	return 0; @@ -2917,8 +2909,7 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)  		ret_val |= e1e_rphy(hw, PHY_1000T_STATUS, &phy->stat1000);  		ret_val |= e1e_rphy(hw, PHY_EXT_STATUS, &phy->estatus);  		if (ret_val) -			ndev_warn(adapter->netdev, -				  "Error reading PHY register\n"); +			e_warn("Error reading PHY register\n");  	} else {  		/*  		 * Do not read PHY registers if link is not up @@ -2943,18 +2934,16 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)  static void e1000_print_link_info(struct e1000_adapter *adapter)  {  	struct e1000_hw *hw = &adapter->hw; -	struct net_device *netdev = adapter->netdev;  	u32 ctrl = er32(CTRL); -	ndev_info(netdev, -		"Link is Up %d Mbps %s, Flow Control: %s\n", -		adapter->link_speed, -		(adapter->link_duplex == FULL_DUPLEX) ? -				"Full Duplex" : "Half Duplex", -		((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ? -				"RX/TX" : -		((ctrl & E1000_CTRL_RFCE) ? "RX" : -		((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" ))); +	e_info("Link is Up %d Mbps %s, Flow Control: %s\n", +	       adapter->link_speed, +	       (adapter->link_duplex == FULL_DUPLEX) ? +	                        "Full Duplex" : "Half Duplex", +	       ((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ? +	                        "RX/TX" : +	       ((ctrl & E1000_CTRL_RFCE) ? "RX" : +	       ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));  }  static bool e1000_has_link(struct e1000_adapter *adapter) @@ -2994,8 +2983,7 @@ static bool e1000_has_link(struct e1000_adapter *adapter)  	if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&  	    (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {  		/* See e1000_kmrn_lock_loss_workaround_ich8lan() */ -		ndev_info(adapter->netdev, -			  "Gigabit has been disabled, downgrading speed\n"); +		e_info("Gigabit has been disabled, downgrading speed\n");  	}  	return link_active; @@ -3096,8 +3084,7 @@ static void e1000_watchdog_task(struct work_struct *work)  				switch (adapter->link_speed) {  				case SPEED_10:  				case SPEED_100: -					ndev_info(netdev, -					"10/100 speed: disabling TSO\n"); +					e_info("10/100 speed: disabling TSO\n");  					netdev->features &= ~NETIF_F_TSO;  					netdev->features &= ~NETIF_F_TSO6;  					break; @@ -3130,7 +3117,7 @@ static void e1000_watchdog_task(struct work_struct *work)  		if (netif_carrier_ok(netdev)) {  			adapter->link_speed = 0;  			adapter->link_duplex = 0; -			ndev_info(netdev, "Link is Down\n"); +			e_info("Link is Down\n");  			netif_carrier_off(netdev);  			netif_tx_stop_all_queues(netdev);  			if (!test_bit(__E1000_DOWN, &adapter->state)) @@ -3604,8 +3591,7 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)  			pull_size = min((unsigned int)4, skb->data_len);  			if (!__pskb_pull_tail(skb, pull_size)) { -				ndev_err(netdev, -					 "__pskb_pull_tail failed.\n"); +				e_err("__pskb_pull_tail failed.\n");  				dev_kfree_skb_any(skb);  				return NETDEV_TX_OK;  			} @@ -3737,25 +3723,25 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)  	if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||  	    (max_frame > MAX_JUMBO_FRAME_SIZE)) { -		ndev_err(netdev, "Invalid MTU setting\n"); +		e_err("Invalid MTU setting\n");  		return -EINVAL;  	}  	/* Jumbo frame size limits */  	if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {  		if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { -			ndev_err(netdev, "Jumbo Frames not supported.\n"); +			e_err("Jumbo Frames not supported.\n");  			return -EINVAL;  		}  		if (adapter->hw.phy.type == e1000_phy_ife) { -			ndev_err(netdev, "Jumbo Frames not supported.\n"); +			e_err("Jumbo Frames not supported.\n");  			return -EINVAL;  		}  	}  #define MAX_STD_JUMBO_FRAME_SIZE 9234  	if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) { -		ndev_err(netdev, "MTU > 9216 not supported.\n"); +		e_err("MTU > 9216 not supported.\n");  		return -EINVAL;  	} @@ -3792,8 +3778,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)  		adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN  					 + ETH_FCS_LEN; -	ndev_info(netdev, "changing MTU from %d to %d\n", -		netdev->mtu, new_mtu); +	e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);  	netdev->mtu = new_mtu;  	if (netif_running(netdev)) @@ -4006,10 +3991,7 @@ static int e1000_resume(struct pci_dev *pdev)  	pci_restore_state(pdev);  	e1000e_disable_l1aspm(pdev); -	if (adapter->need_ioport) -		err = pci_enable_device(pdev); -	else -		err = pci_enable_device_mem(pdev); +	err = pci_enable_device_mem(pdev);  	if (err) {  		dev_err(&pdev->dev,  			"Cannot enable PCI device from suspend\n"); @@ -4043,7 +4025,7 @@ static int e1000_resume(struct pci_dev *pdev)  	 * is up.  For all other cases, let the f/w know that the h/w is now  	 * under the control of the driver.  	 */ -	if (!(adapter->flags & FLAG_HAS_AMT) || !e1000e_check_mng_mode(&adapter->hw)) +	if (!(adapter->flags & FLAG_HAS_AMT))  		e1000_get_hw_control(adapter);  	return 0; @@ -4111,10 +4093,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)  	int err;  	e1000e_disable_l1aspm(pdev); -	if (adapter->need_ioport) -		err = pci_enable_device(pdev); -	else -		err = pci_enable_device_mem(pdev); +	err = pci_enable_device_mem(pdev);  	if (err) {  		dev_err(&pdev->dev,  			"Cannot re-enable PCI device after reset.\n"); @@ -4162,8 +4141,7 @@ static void e1000_io_resume(struct pci_dev *pdev)  	 * is up.  For all other cases, let the f/w know that the h/w is now  	 * under the control of the driver.  	 */ -	if (!(adapter->flags & FLAG_HAS_AMT) || -	    !e1000e_check_mng_mode(&adapter->hw)) +	if (!(adapter->flags & FLAG_HAS_AMT))  		e1000_get_hw_control(adapter);  } @@ -4175,36 +4153,40 @@ static void e1000_print_device_info(struct e1000_adapter *adapter)  	u32 pba_num;  	/* print bus type/speed/width info */ -	ndev_info(netdev, "(PCI Express:2.5GB/s:%s) " -		  "%02x:%02x:%02x:%02x:%02x:%02x\n", -		  /* bus width */ -		 ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" : -		  "Width x1"), -		  /* MAC address */ -		  netdev->dev_addr[0], netdev->dev_addr[1], -		  netdev->dev_addr[2], netdev->dev_addr[3], -		  netdev->dev_addr[4], netdev->dev_addr[5]); -	ndev_info(netdev, "Intel(R) PRO/%s Network Connection\n", -		  (hw->phy.type == e1000_phy_ife) -		   ? "10/100" : "1000"); +	e_info("(PCI Express:2.5GB/s:%s) %02x:%02x:%02x:%02x:%02x:%02x\n", +	       /* bus width */ +	       ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" : +	        "Width x1"), +	       /* MAC address */ +	       netdev->dev_addr[0], netdev->dev_addr[1], +	       netdev->dev_addr[2], netdev->dev_addr[3], +	       netdev->dev_addr[4], netdev->dev_addr[5]); +	e_info("Intel(R) PRO/%s Network Connection\n", +	       (hw->phy.type == e1000_phy_ife) ? "10/100" : "1000");  	e1000e_read_pba_num(hw, &pba_num); -	ndev_info(netdev, "MAC: %d, PHY: %d, PBA No: %06x-%03x\n", -		  hw->mac.type, hw->phy.type, -		  (pba_num >> 8), (pba_num & 0xff)); +	e_info("MAC: %d, PHY: %d, PBA No: %06x-%03x\n", +	       hw->mac.type, hw->phy.type, (pba_num >> 8), (pba_num & 0xff));  } -/** - * e1000e_is_need_ioport - determine if an adapter needs ioport resources or not - * @pdev: PCI device information struct - * - * Returns true if an adapters needs ioport resources - **/ -static int e1000e_is_need_ioport(struct pci_dev *pdev) +static void e1000_eeprom_checks(struct e1000_adapter *adapter)  { -	switch (pdev->device) { -	/* Currently there are no adapters that need ioport resources */ -	default: -		return false; +	struct e1000_hw *hw = &adapter->hw; +	int ret_val; +	u16 buf = 0; + +	if (hw->mac.type != e1000_82573) +		return; + +	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf); +	if (!(le16_to_cpu(buf) & (1 << 0))) { +		/* Deep Smart Power Down (DSPD) */ +		e_warn("Warning: detected DSPD enabled in EEPROM\n"); +	} + +	ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf); +	if (le16_to_cpu(buf) & (3 << 2)) { +		/* ASPM enable */ +		e_warn("Warning: detected ASPM enabled in EEPROM\n");  	}  } @@ -4233,19 +4215,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev,  	int i, err, pci_using_dac;  	u16 eeprom_data = 0;  	u16 eeprom_apme_mask = E1000_EEPROM_APME; -	int bars, need_ioport;  	e1000e_disable_l1aspm(pdev); -	/* do not allocate ioport bars when not needed */ -	need_ioport = e1000e_is_need_ioport(pdev); -	if (need_ioport) { -		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO); -		err = pci_enable_device(pdev); -	} else { -		bars = pci_select_bars(pdev, IORESOURCE_MEM); -		err = pci_enable_device_mem(pdev); -	} +	err = pci_enable_device_mem(pdev);  	if (err)  		return err; @@ -4268,7 +4241,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev,  		}  	} -	err = pci_request_selected_regions(pdev, bars, e1000e_driver_name); +	err = pci_request_selected_regions(pdev, +	                                  pci_select_bars(pdev, IORESOURCE_MEM), +	                                  e1000e_driver_name);  	if (err)  		goto err_pci_reg; @@ -4293,8 +4268,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,  	adapter->hw.adapter = adapter;  	adapter->hw.mac.type = ei->mac;  	adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1; -	adapter->bars = bars; -	adapter->need_ioport = need_ioport;  	mmio_start = pci_resource_start(pdev, 0);  	mmio_len = pci_resource_len(pdev, 0); @@ -4366,8 +4339,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,  	}  	if (e1000_check_reset_block(&adapter->hw)) -		ndev_info(netdev, -			  "PHY reset is blocked due to SOL/IDER session.\n"); +		e_info("PHY reset is blocked due to SOL/IDER session.\n");  	netdev->features = NETIF_F_SG |  			   NETIF_F_HW_CSUM | @@ -4411,25 +4383,26 @@ static int __devinit e1000_probe(struct pci_dev *pdev,  		if (e1000_validate_nvm_checksum(&adapter->hw) >= 0)  			break;  		if (i == 2) { -			ndev_err(netdev, "The NVM Checksum Is Not Valid\n"); +			e_err("The NVM Checksum Is Not Valid\n");  			err = -EIO;  			goto err_eeprom;  		}  	} +	e1000_eeprom_checks(adapter); +  	/* copy the MAC address out of the NVM */  	if (e1000e_read_mac_addr(&adapter->hw)) -		ndev_err(netdev, "NVM Read Error while reading MAC address\n"); +		e_err("NVM Read Error while reading MAC address\n");  	memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);  	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);  	if (!is_valid_ether_addr(netdev->perm_addr)) { -		ndev_err(netdev, "Invalid MAC Address: " -			 "%02x:%02x:%02x:%02x:%02x:%02x\n", -			 netdev->perm_addr[0], netdev->perm_addr[1], -			 netdev->perm_addr[2], netdev->perm_addr[3], -			 netdev->perm_addr[4], netdev->perm_addr[5]); +		e_err("Invalid MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", +		      netdev->perm_addr[0], netdev->perm_addr[1], +		      netdev->perm_addr[2], netdev->perm_addr[3], +		      netdev->perm_addr[4], netdev->perm_addr[5]);  		err = -EIO;  		goto err_eeprom;  	} @@ -4499,8 +4472,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,  	 * is up.  For all other cases, let the f/w know that the h/w is now  	 * under the control of the driver.  	 */ -	if (!(adapter->flags & FLAG_HAS_AMT) || -	    !e1000e_check_mng_mode(&adapter->hw)) +	if (!(adapter->flags & FLAG_HAS_AMT))  		e1000_get_hw_control(adapter);  	/* tell the stack to leave us alone until e1000_open() is called */ @@ -4517,24 +4489,25 @@ static int __devinit e1000_probe(struct pci_dev *pdev,  	return 0;  err_register: -err_hw_init: -	e1000_release_hw_control(adapter); +	if (!(adapter->flags & FLAG_HAS_AMT)) +		e1000_release_hw_control(adapter);  err_eeprom:  	if (!e1000_check_reset_block(&adapter->hw))  		e1000_phy_hw_reset(&adapter->hw); +err_hw_init: -	if (adapter->hw.flash_address) -		iounmap(adapter->hw.flash_address); - -err_flashmap:  	kfree(adapter->tx_ring);  	kfree(adapter->rx_ring);  err_sw_init: +	if (adapter->hw.flash_address) +		iounmap(adapter->hw.flash_address); +err_flashmap:  	iounmap(adapter->hw.hw_addr);  err_ioremap:  	free_netdev(netdev);  err_alloc_etherdev: -	pci_release_selected_regions(pdev, bars); +	pci_release_selected_regions(pdev, +	                             pci_select_bars(pdev, IORESOURCE_MEM));  err_pci_reg:  err_dma:  	pci_disable_device(pdev); @@ -4582,7 +4555,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev)  	iounmap(adapter->hw.hw_addr);  	if (adapter->hw.flash_address)  		iounmap(adapter->hw.flash_address); -	pci_release_selected_regions(pdev, adapter->bars); +	pci_release_selected_regions(pdev, +	                             pci_select_bars(pdev, IORESOURCE_MEM));  	free_netdev(netdev);  | 
