diff options
author | Sasha Neftin <sasha.neftin@intel.com> | 2018-10-11 03:17:13 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2018-10-17 16:14:03 -0400 |
commit | c9a11c23ceb65db7ecc5735e7428311d70e74ba9 (patch) | |
tree | 9d52fe6e7e45df154f1949049c71a40386f4f0c8 /drivers/net/ethernet/intel/igc/igc_main.c | |
parent | 146740f9abc4976e4f0af1aa302efee1c699d2e4 (diff) |
igc: Add netdev
Now that we have the ability to configure the basic settings on the device
we can start allocating and configuring a netdev for the interface.
Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/igc/igc_main.c')
-rw-r--r-- | drivers/net/ethernet/intel/igc/igc_main.c | 471 |
1 files changed, 470 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 6a881753f5ce..7c5b0d2f16bf 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c | |||
@@ -3,6 +3,8 @@ | |||
3 | 3 | ||
4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
6 | #include <linux/if_vlan.h> | ||
7 | #include <linux/aer.h> | ||
6 | 8 | ||
7 | #include "igc.h" | 9 | #include "igc.h" |
8 | #include "igc_hw.h" | 10 | #include "igc_hw.h" |
@@ -10,10 +12,14 @@ | |||
10 | #define DRV_VERSION "0.0.1-k" | 12 | #define DRV_VERSION "0.0.1-k" |
11 | #define DRV_SUMMARY "Intel(R) 2.5G Ethernet Linux Driver" | 13 | #define DRV_SUMMARY "Intel(R) 2.5G Ethernet Linux Driver" |
12 | 14 | ||
15 | static int debug = -1; | ||
16 | |||
13 | MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); | 17 | MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); |
14 | MODULE_DESCRIPTION(DRV_SUMMARY); | 18 | MODULE_DESCRIPTION(DRV_SUMMARY); |
15 | MODULE_LICENSE("GPL v2"); | 19 | MODULE_LICENSE("GPL v2"); |
16 | MODULE_VERSION(DRV_VERSION); | 20 | MODULE_VERSION(DRV_VERSION); |
21 | module_param(debug, int, 0); | ||
22 | MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); | ||
17 | 23 | ||
18 | char igc_driver_name[] = "igc"; | 24 | char igc_driver_name[] = "igc"; |
19 | char igc_driver_version[] = DRV_VERSION; | 25 | char igc_driver_version[] = DRV_VERSION; |
@@ -32,6 +38,364 @@ MODULE_DEVICE_TABLE(pci, igc_pci_tbl); | |||
32 | 38 | ||
33 | /* forward declaration */ | 39 | /* forward declaration */ |
34 | static int igc_sw_init(struct igc_adapter *); | 40 | static int igc_sw_init(struct igc_adapter *); |
41 | static void igc_configure(struct igc_adapter *adapter); | ||
42 | static void igc_power_down_link(struct igc_adapter *adapter); | ||
43 | static void igc_set_default_mac_filter(struct igc_adapter *adapter); | ||
44 | |||
45 | static void igc_reset(struct igc_adapter *adapter) | ||
46 | { | ||
47 | if (!netif_running(adapter->netdev)) | ||
48 | igc_power_down_link(adapter); | ||
49 | } | ||
50 | |||
51 | /** | ||
52 | * igc_power_up_link - Power up the phy/serdes link | ||
53 | * @adapter: address of board private structure | ||
54 | */ | ||
55 | static void igc_power_up_link(struct igc_adapter *adapter) | ||
56 | { | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * igc_power_down_link - Power down the phy/serdes link | ||
61 | * @adapter: address of board private structure | ||
62 | */ | ||
63 | static void igc_power_down_link(struct igc_adapter *adapter) | ||
64 | { | ||
65 | } | ||
66 | |||
67 | /** | ||
68 | * igc_release_hw_control - release control of the h/w to f/w | ||
69 | * @adapter: address of board private structure | ||
70 | * | ||
71 | * igc_release_hw_control resets CTRL_EXT:DRV_LOAD bit. | ||
72 | * For ASF and Pass Through versions of f/w this means that the | ||
73 | * driver is no longer loaded. | ||
74 | */ | ||
75 | static void igc_release_hw_control(struct igc_adapter *adapter) | ||
76 | { | ||
77 | struct igc_hw *hw = &adapter->hw; | ||
78 | u32 ctrl_ext; | ||
79 | |||
80 | /* Let firmware take over control of h/w */ | ||
81 | ctrl_ext = rd32(IGC_CTRL_EXT); | ||
82 | wr32(IGC_CTRL_EXT, | ||
83 | ctrl_ext & ~IGC_CTRL_EXT_DRV_LOAD); | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * igc_get_hw_control - get control of the h/w from f/w | ||
88 | * @adapter: address of board private structure | ||
89 | * | ||
90 | * igc_get_hw_control sets CTRL_EXT:DRV_LOAD bit. | ||
91 | * For ASF and Pass Through versions of f/w this means that | ||
92 | * the driver is loaded. | ||
93 | */ | ||
94 | static void igc_get_hw_control(struct igc_adapter *adapter) | ||
95 | { | ||
96 | struct igc_hw *hw = &adapter->hw; | ||
97 | u32 ctrl_ext; | ||
98 | |||
99 | /* Let firmware know the driver has taken over */ | ||
100 | ctrl_ext = rd32(IGC_CTRL_EXT); | ||
101 | wr32(IGC_CTRL_EXT, | ||
102 | ctrl_ext | IGC_CTRL_EXT_DRV_LOAD); | ||
103 | } | ||
104 | |||
105 | /** | ||
106 | * igc_set_mac - Change the Ethernet Address of the NIC | ||
107 | * @netdev: network interface device structure | ||
108 | * @p: pointer to an address structure | ||
109 | * | ||
110 | * Returns 0 on success, negative on failure | ||
111 | */ | ||
112 | static int igc_set_mac(struct net_device *netdev, void *p) | ||
113 | { | ||
114 | struct igc_adapter *adapter = netdev_priv(netdev); | ||
115 | struct igc_hw *hw = &adapter->hw; | ||
116 | struct sockaddr *addr = p; | ||
117 | |||
118 | if (!is_valid_ether_addr(addr->sa_data)) | ||
119 | return -EADDRNOTAVAIL; | ||
120 | |||
121 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | ||
122 | memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len); | ||
123 | |||
124 | /* set the correct pool for the new PF MAC address in entry 0 */ | ||
125 | igc_set_default_mac_filter(adapter); | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static netdev_tx_t igc_xmit_frame(struct sk_buff *skb, | ||
131 | struct net_device *netdev) | ||
132 | { | ||
133 | dev_kfree_skb_any(skb); | ||
134 | return NETDEV_TX_OK; | ||
135 | } | ||
136 | |||
137 | /** | ||
138 | * igc_ioctl - I/O control method | ||
139 | * @netdev: network interface device structure | ||
140 | * @ifreq: frequency | ||
141 | * @cmd: command | ||
142 | */ | ||
143 | static int igc_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | ||
144 | { | ||
145 | switch (cmd) { | ||
146 | default: | ||
147 | return -EOPNOTSUPP; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | /** | ||
152 | * igc_up - Open the interface and prepare it to handle traffic | ||
153 | * @adapter: board private structure | ||
154 | */ | ||
155 | static void igc_up(struct igc_adapter *adapter) | ||
156 | { | ||
157 | int i = 0; | ||
158 | |||
159 | /* hardware has been reset, we need to reload some things */ | ||
160 | igc_configure(adapter); | ||
161 | |||
162 | clear_bit(__IGC_DOWN, &adapter->state); | ||
163 | |||
164 | for (i = 0; i < adapter->num_q_vectors; i++) | ||
165 | napi_enable(&adapter->q_vector[i]->napi); | ||
166 | } | ||
167 | |||
168 | /** | ||
169 | * igc_update_stats - Update the board statistics counters | ||
170 | * @adapter: board private structure | ||
171 | */ | ||
172 | static void igc_update_stats(struct igc_adapter *adapter) | ||
173 | { | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * igc_down - Close the interface | ||
178 | * @adapter: board private structure | ||
179 | */ | ||
180 | static void igc_down(struct igc_adapter *adapter) | ||
181 | { | ||
182 | struct net_device *netdev = adapter->netdev; | ||
183 | int i = 0; | ||
184 | |||
185 | set_bit(__IGC_DOWN, &adapter->state); | ||
186 | |||
187 | /* set trans_start so we don't get spurious watchdogs during reset */ | ||
188 | netif_trans_update(netdev); | ||
189 | |||
190 | netif_carrier_off(netdev); | ||
191 | netif_tx_stop_all_queues(netdev); | ||
192 | |||
193 | for (i = 0; i < adapter->num_q_vectors; i++) | ||
194 | napi_disable(&adapter->q_vector[i]->napi); | ||
195 | |||
196 | adapter->link_speed = 0; | ||
197 | adapter->link_duplex = 0; | ||
198 | } | ||
199 | |||
200 | /** | ||
201 | * igc_change_mtu - Change the Maximum Transfer Unit | ||
202 | * @netdev: network interface device structure | ||
203 | * @new_mtu: new value for maximum frame size | ||
204 | * | ||
205 | * Returns 0 on success, negative on failure | ||
206 | */ | ||
207 | static int igc_change_mtu(struct net_device *netdev, int new_mtu) | ||
208 | { | ||
209 | int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; | ||
210 | struct igc_adapter *adapter = netdev_priv(netdev); | ||
211 | struct pci_dev *pdev = adapter->pdev; | ||
212 | |||
213 | /* adjust max frame to be at least the size of a standard frame */ | ||
214 | if (max_frame < (ETH_FRAME_LEN + ETH_FCS_LEN)) | ||
215 | max_frame = ETH_FRAME_LEN + ETH_FCS_LEN; | ||
216 | |||
217 | while (test_and_set_bit(__IGC_RESETTING, &adapter->state)) | ||
218 | usleep_range(1000, 2000); | ||
219 | |||
220 | /* igc_down has a dependency on max_frame_size */ | ||
221 | adapter->max_frame_size = max_frame; | ||
222 | |||
223 | if (netif_running(netdev)) | ||
224 | igc_down(adapter); | ||
225 | |||
226 | dev_info(&pdev->dev, "changing MTU from %d to %d\n", | ||
227 | netdev->mtu, new_mtu); | ||
228 | netdev->mtu = new_mtu; | ||
229 | |||
230 | if (netif_running(netdev)) | ||
231 | igc_up(adapter); | ||
232 | else | ||
233 | igc_reset(adapter); | ||
234 | |||
235 | clear_bit(__IGC_RESETTING, &adapter->state); | ||
236 | |||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | /** | ||
241 | * igc_get_stats - Get System Network Statistics | ||
242 | * @netdev: network interface device structure | ||
243 | * | ||
244 | * Returns the address of the device statistics structure. | ||
245 | * The statistics are updated here and also from the timer callback. | ||
246 | */ | ||
247 | static struct net_device_stats *igc_get_stats(struct net_device *netdev) | ||
248 | { | ||
249 | struct igc_adapter *adapter = netdev_priv(netdev); | ||
250 | |||
251 | if (!test_bit(__IGC_RESETTING, &adapter->state)) | ||
252 | igc_update_stats(adapter); | ||
253 | |||
254 | /* only return the current stats */ | ||
255 | return &netdev->stats; | ||
256 | } | ||
257 | |||
258 | /** | ||
259 | * igc_configure - configure the hardware for RX and TX | ||
260 | * @adapter: private board structure | ||
261 | */ | ||
262 | static void igc_configure(struct igc_adapter *adapter) | ||
263 | { | ||
264 | igc_get_hw_control(adapter); | ||
265 | } | ||
266 | |||
267 | /** | ||
268 | * igc_rar_set_index - Sync RAL[index] and RAH[index] registers with MAC table | ||
269 | * @adapter: Pointer to adapter structure | ||
270 | * @index: Index of the RAR entry which need to be synced with MAC table | ||
271 | */ | ||
272 | static void igc_rar_set_index(struct igc_adapter *adapter, u32 index) | ||
273 | { | ||
274 | u8 *addr = adapter->mac_table[index].addr; | ||
275 | struct igc_hw *hw = &adapter->hw; | ||
276 | u32 rar_low, rar_high; | ||
277 | |||
278 | /* HW expects these to be in network order when they are plugged | ||
279 | * into the registers which are little endian. In order to guarantee | ||
280 | * that ordering we need to do an leXX_to_cpup here in order to be | ||
281 | * ready for the byteswap that occurs with writel | ||
282 | */ | ||
283 | rar_low = le32_to_cpup((__le32 *)(addr)); | ||
284 | rar_high = le16_to_cpup((__le16 *)(addr + 4)); | ||
285 | |||
286 | /* Indicate to hardware the Address is Valid. */ | ||
287 | if (adapter->mac_table[index].state & IGC_MAC_STATE_IN_USE) { | ||
288 | if (is_valid_ether_addr(addr)) | ||
289 | rar_high |= IGC_RAH_AV; | ||
290 | |||
291 | rar_high |= IGC_RAH_POOL_1 << | ||
292 | adapter->mac_table[index].queue; | ||
293 | } | ||
294 | |||
295 | wr32(IGC_RAL(index), rar_low); | ||
296 | wrfl(); | ||
297 | wr32(IGC_RAH(index), rar_high); | ||
298 | wrfl(); | ||
299 | } | ||
300 | |||
301 | /* Set default MAC address for the PF in the first RAR entry */ | ||
302 | static void igc_set_default_mac_filter(struct igc_adapter *adapter) | ||
303 | { | ||
304 | struct igc_mac_addr *mac_table = &adapter->mac_table[0]; | ||
305 | |||
306 | ether_addr_copy(mac_table->addr, adapter->hw.mac.addr); | ||
307 | mac_table->state = IGC_MAC_STATE_DEFAULT | IGC_MAC_STATE_IN_USE; | ||
308 | |||
309 | igc_rar_set_index(adapter, 0); | ||
310 | } | ||
311 | |||
312 | /** | ||
313 | * igc_open - Called when a network interface is made active | ||
314 | * @netdev: network interface device structure | ||
315 | * | ||
316 | * Returns 0 on success, negative value on failure | ||
317 | * | ||
318 | * The open entry point is called when a network interface is made | ||
319 | * active by the system (IFF_UP). At this point all resources needed | ||
320 | * for transmit and receive operations are allocated, the interrupt | ||
321 | * handler is registered with the OS, the watchdog timer is started, | ||
322 | * and the stack is notified that the interface is ready. | ||
323 | */ | ||
324 | static int __igc_open(struct net_device *netdev, bool resuming) | ||
325 | { | ||
326 | struct igc_adapter *adapter = netdev_priv(netdev); | ||
327 | struct igc_hw *hw = &adapter->hw; | ||
328 | int i = 0; | ||
329 | |||
330 | /* disallow open during test */ | ||
331 | |||
332 | if (test_bit(__IGC_TESTING, &adapter->state)) { | ||
333 | WARN_ON(resuming); | ||
334 | return -EBUSY; | ||
335 | } | ||
336 | |||
337 | netif_carrier_off(netdev); | ||
338 | |||
339 | igc_power_up_link(adapter); | ||
340 | |||
341 | igc_configure(adapter); | ||
342 | |||
343 | clear_bit(__IGC_DOWN, &adapter->state); | ||
344 | |||
345 | for (i = 0; i < adapter->num_q_vectors; i++) | ||
346 | napi_enable(&adapter->q_vector[i]->napi); | ||
347 | |||
348 | /* start the watchdog. */ | ||
349 | hw->mac.get_link_status = 1; | ||
350 | |||
351 | return IGC_SUCCESS; | ||
352 | } | ||
353 | |||
354 | static int igc_open(struct net_device *netdev) | ||
355 | { | ||
356 | return __igc_open(netdev, false); | ||
357 | } | ||
358 | |||
359 | /** | ||
360 | * igc_close - Disables a network interface | ||
361 | * @netdev: network interface device structure | ||
362 | * | ||
363 | * Returns 0, this is not allowed to fail | ||
364 | * | ||
365 | * The close entry point is called when an interface is de-activated | ||
366 | * by the OS. The hardware is still under the driver's control, but | ||
367 | * needs to be disabled. A global MAC reset is issued to stop the | ||
368 | * hardware, and all transmit and receive resources are freed. | ||
369 | */ | ||
370 | static int __igc_close(struct net_device *netdev, bool suspending) | ||
371 | { | ||
372 | struct igc_adapter *adapter = netdev_priv(netdev); | ||
373 | |||
374 | WARN_ON(test_bit(__IGC_RESETTING, &adapter->state)); | ||
375 | |||
376 | igc_down(adapter); | ||
377 | |||
378 | igc_release_hw_control(adapter); | ||
379 | |||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static int igc_close(struct net_device *netdev) | ||
384 | { | ||
385 | if (netif_device_present(netdev) || netdev->dismantle) | ||
386 | return __igc_close(netdev, false); | ||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | static const struct net_device_ops igc_netdev_ops = { | ||
391 | .ndo_open = igc_open, | ||
392 | .ndo_stop = igc_close, | ||
393 | .ndo_start_xmit = igc_xmit_frame, | ||
394 | .ndo_set_mac_address = igc_set_mac, | ||
395 | .ndo_change_mtu = igc_change_mtu, | ||
396 | .ndo_get_stats = igc_get_stats, | ||
397 | .ndo_do_ioctl = igc_ioctl, | ||
398 | }; | ||
35 | 399 | ||
36 | /* PCIe configuration access */ | 400 | /* PCIe configuration access */ |
37 | void igc_read_pci_cfg(struct igc_hw *hw, u32 reg, u16 *value) | 401 | void igc_read_pci_cfg(struct igc_hw *hw, u32 reg, u16 *value) |
@@ -78,6 +442,7 @@ s32 igc_write_pcie_cap_reg(struct igc_hw *hw, u32 reg, u16 *value) | |||
78 | 442 | ||
79 | u32 igc_rd32(struct igc_hw *hw, u32 reg) | 443 | u32 igc_rd32(struct igc_hw *hw, u32 reg) |
80 | { | 444 | { |
445 | struct igc_adapter *igc = container_of(hw, struct igc_adapter, hw); | ||
81 | u8 __iomem *hw_addr = READ_ONCE(hw->hw_addr); | 446 | u8 __iomem *hw_addr = READ_ONCE(hw->hw_addr); |
82 | u32 value = 0; | 447 | u32 value = 0; |
83 | 448 | ||
@@ -87,8 +452,13 @@ u32 igc_rd32(struct igc_hw *hw, u32 reg) | |||
87 | value = readl(&hw_addr[reg]); | 452 | value = readl(&hw_addr[reg]); |
88 | 453 | ||
89 | /* reads should not return all F's */ | 454 | /* reads should not return all F's */ |
90 | if (!(~value) && (!reg || !(~readl(hw_addr)))) | 455 | if (!(~value) && (!reg || !(~readl(hw_addr)))) { |
456 | struct net_device *netdev = igc->netdev; | ||
457 | |||
91 | hw->hw_addr = NULL; | 458 | hw->hw_addr = NULL; |
459 | netif_device_detach(netdev); | ||
460 | netdev_err(netdev, "PCIe link lost, device now detached\n"); | ||
461 | } | ||
92 | 462 | ||
93 | return value; | 463 | return value; |
94 | } | 464 | } |
@@ -108,6 +478,8 @@ static int igc_probe(struct pci_dev *pdev, | |||
108 | const struct pci_device_id *ent) | 478 | const struct pci_device_id *ent) |
109 | { | 479 | { |
110 | struct igc_adapter *adapter; | 480 | struct igc_adapter *adapter; |
481 | struct net_device *netdev; | ||
482 | struct igc_hw *hw; | ||
111 | int err, pci_using_dac; | 483 | int err, pci_using_dac; |
112 | 484 | ||
113 | err = pci_enable_device_mem(pdev); | 485 | err = pci_enable_device_mem(pdev); |
@@ -140,17 +512,94 @@ static int igc_probe(struct pci_dev *pdev, | |||
140 | if (err) | 512 | if (err) |
141 | goto err_pci_reg; | 513 | goto err_pci_reg; |
142 | 514 | ||
515 | pci_enable_pcie_error_reporting(pdev); | ||
516 | |||
143 | pci_set_master(pdev); | 517 | pci_set_master(pdev); |
518 | |||
519 | err = -ENOMEM; | ||
520 | netdev = alloc_etherdev_mq(sizeof(struct igc_adapter), | ||
521 | IGC_MAX_TX_QUEUES); | ||
522 | |||
523 | if (!netdev) | ||
524 | goto err_alloc_etherdev; | ||
525 | |||
526 | SET_NETDEV_DEV(netdev, &pdev->dev); | ||
527 | |||
528 | pci_set_drvdata(pdev, netdev); | ||
529 | adapter = netdev_priv(netdev); | ||
530 | adapter->netdev = netdev; | ||
531 | adapter->pdev = pdev; | ||
532 | hw = &adapter->hw; | ||
533 | hw->back = adapter; | ||
534 | adapter->port_num = hw->bus.func; | ||
535 | adapter->msg_enable = GENMASK(debug - 1, 0); | ||
536 | |||
144 | err = pci_save_state(pdev); | 537 | err = pci_save_state(pdev); |
538 | if (err) | ||
539 | goto err_ioremap; | ||
540 | |||
541 | err = -EIO; | ||
542 | adapter->io_addr = ioremap(pci_resource_start(pdev, 0), | ||
543 | pci_resource_len(pdev, 0)); | ||
544 | if (!adapter->io_addr) | ||
545 | goto err_ioremap; | ||
546 | |||
547 | /* hw->hw_addr can be zeroed, so use adapter->io_addr for unmap */ | ||
548 | hw->hw_addr = adapter->io_addr; | ||
549 | |||
550 | netdev->netdev_ops = &igc_netdev_ops; | ||
551 | |||
552 | netdev->watchdog_timeo = 5 * HZ; | ||
553 | |||
554 | netdev->mem_start = pci_resource_start(pdev, 0); | ||
555 | netdev->mem_end = pci_resource_end(pdev, 0); | ||
556 | |||
557 | /* PCI config space info */ | ||
558 | hw->vendor_id = pdev->vendor; | ||
559 | hw->device_id = pdev->device; | ||
560 | hw->revision_id = pdev->revision; | ||
561 | hw->subsystem_vendor_id = pdev->subsystem_vendor; | ||
562 | hw->subsystem_device_id = pdev->subsystem_device; | ||
145 | 563 | ||
146 | /* setup the private structure */ | 564 | /* setup the private structure */ |
147 | err = igc_sw_init(adapter); | 565 | err = igc_sw_init(adapter); |
148 | if (err) | 566 | if (err) |
149 | goto err_sw_init; | 567 | goto err_sw_init; |
150 | 568 | ||
569 | /* MTU range: 68 - 9216 */ | ||
570 | netdev->min_mtu = ETH_MIN_MTU; | ||
571 | netdev->max_mtu = MAX_STD_JUMBO_FRAME_SIZE; | ||
572 | |||
573 | /* reset the hardware with the new settings */ | ||
574 | igc_reset(adapter); | ||
575 | |||
576 | /* let the f/w know that the h/w is now under the control of the | ||
577 | * driver. | ||
578 | */ | ||
579 | igc_get_hw_control(adapter); | ||
580 | |||
581 | strncpy(netdev->name, "eth%d", IFNAMSIZ); | ||
582 | err = register_netdev(netdev); | ||
583 | if (err) | ||
584 | goto err_register; | ||
585 | |||
586 | /* carrier off reporting is important to ethtool even BEFORE open */ | ||
587 | netif_carrier_off(netdev); | ||
588 | |||
589 | /* print pcie link status and MAC address */ | ||
590 | pcie_print_link_status(pdev); | ||
591 | netdev_info(netdev, "MAC: %pM\n", netdev->dev_addr); | ||
592 | |||
151 | return 0; | 593 | return 0; |
152 | 594 | ||
595 | err_register: | ||
596 | igc_release_hw_control(adapter); | ||
153 | err_sw_init: | 597 | err_sw_init: |
598 | err_ioremap: | ||
599 | free_netdev(netdev); | ||
600 | err_alloc_etherdev: | ||
601 | pci_release_selected_regions(pdev, | ||
602 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
154 | err_pci_reg: | 603 | err_pci_reg: |
155 | err_dma: | 604 | err_dma: |
156 | pci_disable_device(pdev); | 605 | pci_disable_device(pdev); |
@@ -168,9 +617,22 @@ err_dma: | |||
168 | */ | 617 | */ |
169 | static void igc_remove(struct pci_dev *pdev) | 618 | static void igc_remove(struct pci_dev *pdev) |
170 | { | 619 | { |
620 | struct net_device *netdev = pci_get_drvdata(pdev); | ||
621 | struct igc_adapter *adapter = netdev_priv(netdev); | ||
622 | |||
623 | set_bit(__IGC_DOWN, &adapter->state); | ||
624 | flush_scheduled_work(); | ||
625 | |||
626 | /* Release control of h/w to f/w. If f/w is AMT enabled, this | ||
627 | * would have already happened in close and is redundant. | ||
628 | */ | ||
629 | igc_release_hw_control(adapter); | ||
630 | unregister_netdev(netdev); | ||
631 | |||
171 | pci_release_selected_regions(pdev, | 632 | pci_release_selected_regions(pdev, |
172 | pci_select_bars(pdev, IORESOURCE_MEM)); | 633 | pci_select_bars(pdev, IORESOURCE_MEM)); |
173 | 634 | ||
635 | free_netdev(netdev); | ||
174 | pci_disable_device(pdev); | 636 | pci_disable_device(pdev); |
175 | } | 637 | } |
176 | 638 | ||
@@ -191,6 +653,7 @@ static struct pci_driver igc_driver = { | |||
191 | */ | 653 | */ |
192 | static int igc_sw_init(struct igc_adapter *adapter) | 654 | static int igc_sw_init(struct igc_adapter *adapter) |
193 | { | 655 | { |
656 | struct net_device *netdev = adapter->netdev; | ||
194 | struct pci_dev *pdev = adapter->pdev; | 657 | struct pci_dev *pdev = adapter->pdev; |
195 | struct igc_hw *hw = &adapter->hw; | 658 | struct igc_hw *hw = &adapter->hw; |
196 | 659 | ||
@@ -205,6 +668,12 @@ static int igc_sw_init(struct igc_adapter *adapter) | |||
205 | 668 | ||
206 | pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word); | 669 | pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word); |
207 | 670 | ||
671 | /* adjust max frame to be at least the size of a standard frame */ | ||
672 | adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN + | ||
673 | VLAN_HLEN; | ||
674 | |||
675 | set_bit(__IGC_DOWN, &adapter->state); | ||
676 | |||
208 | return 0; | 677 | return 0; |
209 | } | 678 | } |
210 | 679 | ||