fm10k: Add support for ndo_open/stop
[deliverable/linux.git] / drivers / net / ethernet / intel / fm10k / fm10k_netdev.c
CommitLineData
0e7b3644
AD
1/* Intel Ethernet Switch Host Interface Driver
2 * Copyright(c) 2013 - 2014 Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * The full GNU General Public License is included in this distribution in
14 * the file called "COPYING".
15 *
16 * Contact Information:
17 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
18 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
19 */
20
21#include "fm10k.h"
22
504c5eac
AD
23/**
24 * fm10k_request_glort_range - Request GLORTs for use in configuring rules
25 * @interface: board private structure
26 *
27 * This function allocates a range of glorts for this inteface to use.
28 **/
29static void fm10k_request_glort_range(struct fm10k_intfc *interface)
30{
31 struct fm10k_hw *hw = &interface->hw;
32 u16 mask = (~hw->mac.dglort_map) >> FM10K_DGLORTMAP_MASK_SHIFT;
33
34 /* establish GLORT base */
35 interface->glort = hw->mac.dglort_map & FM10K_DGLORTMAP_NONE;
36 interface->glort_count = 0;
37
38 /* nothing we can do until mask is allocated */
39 if (hw->mac.dglort_map == FM10K_DGLORTMAP_NONE)
40 return;
41
42 interface->glort_count = mask + 1;
43}
44
45/**
46 * fm10k_open - Called when a network interface is made active
47 * @netdev: network interface device structure
48 *
49 * Returns 0 on success, negative value on failure
50 *
51 * The open entry point is called when a network interface is made
52 * active by the system (IFF_UP). At this point all resources needed
53 * for transmit and receive operations are allocated, the interrupt
54 * handler is registered with the OS, the watchdog timer is started,
55 * and the stack is notified that the interface is ready.
56 **/
57int fm10k_open(struct net_device *netdev)
58{
59 struct fm10k_intfc *interface = netdev_priv(netdev);
60
61 /* setup GLORT assignment for this port */
62 fm10k_request_glort_range(interface);
63
64 fm10k_up(interface);
65
66 return 0;
67}
68
69/**
70 * fm10k_close - Disables a network interface
71 * @netdev: network interface device structure
72 *
73 * Returns 0, this is not allowed to fail
74 *
75 * The close entry point is called when an interface is de-activated
76 * by the OS. The hardware is still under the drivers control, but
77 * needs to be disabled. A global MAC reset is issued to stop the
78 * hardware, and all transmit and receive resources are freed.
79 **/
80int fm10k_close(struct net_device *netdev)
81{
82 struct fm10k_intfc *interface = netdev_priv(netdev);
83
84 fm10k_down(interface);
85
86 return 0;
87}
88
0e7b3644
AD
89static netdev_tx_t fm10k_xmit_frame(struct sk_buff *skb, struct net_device *dev)
90{
91 dev_kfree_skb_any(skb);
92 return NETDEV_TX_OK;
93}
94
95static int fm10k_change_mtu(struct net_device *dev, int new_mtu)
96{
97 if (new_mtu < 68 || new_mtu > FM10K_MAX_JUMBO_FRAME_SIZE)
98 return -EINVAL;
99
100 dev->mtu = new_mtu;
101
102 return 0;
103}
104
8f5e20d4
AD
105static int fm10k_uc_vlan_unsync(struct net_device *netdev,
106 const unsigned char *uc_addr)
107{
108 struct fm10k_intfc *interface = netdev_priv(netdev);
109 struct fm10k_hw *hw = &interface->hw;
110 u16 glort = interface->glort;
111 u16 vid = interface->vid;
112 bool set = !!(vid / VLAN_N_VID);
113 int err;
114
115 /* drop any leading bits on the VLAN ID */
116 vid &= VLAN_N_VID - 1;
117
118 err = hw->mac.ops.update_uc_addr(hw, glort, uc_addr, vid, set, 0);
119 if (err)
120 return err;
121
122 /* return non-zero value as we are only doing a partial sync/unsync */
123 return 1;
124}
125
126static int fm10k_mc_vlan_unsync(struct net_device *netdev,
127 const unsigned char *mc_addr)
128{
129 struct fm10k_intfc *interface = netdev_priv(netdev);
130 struct fm10k_hw *hw = &interface->hw;
131 u16 glort = interface->glort;
132 u16 vid = interface->vid;
133 bool set = !!(vid / VLAN_N_VID);
134 int err;
135
136 /* drop any leading bits on the VLAN ID */
137 vid &= VLAN_N_VID - 1;
138
139 err = hw->mac.ops.update_mc_addr(hw, glort, mc_addr, vid, set);
140 if (err)
141 return err;
142
143 /* return non-zero value as we are only doing a partial sync/unsync */
144 return 1;
145}
146
147static int fm10k_update_vid(struct net_device *netdev, u16 vid, bool set)
148{
149 struct fm10k_intfc *interface = netdev_priv(netdev);
150 struct fm10k_hw *hw = &interface->hw;
151 s32 err;
152
153 /* updates do not apply to VLAN 0 */
154 if (!vid)
155 return 0;
156
157 if (vid >= VLAN_N_VID)
158 return -EINVAL;
159
160 /* Verify we have permission to add VLANs */
161 if (hw->mac.vlan_override)
162 return -EACCES;
163
164 /* if default VLAN is already present do nothing */
165 if (vid == hw->mac.default_vid)
166 return -EBUSY;
167
168 /* update active_vlans bitmask */
169 set_bit(vid, interface->active_vlans);
170 if (!set)
171 clear_bit(vid, interface->active_vlans);
172
173 fm10k_mbx_lock(interface);
174
175 /* only need to update the VLAN if not in promiscous mode */
176 if (!(netdev->flags & IFF_PROMISC)) {
177 err = hw->mac.ops.update_vlan(hw, vid, 0, set);
178 if (err)
179 return err;
180 }
181
182 /* update our base MAC address */
183 err = hw->mac.ops.update_uc_addr(hw, interface->glort, hw->mac.addr,
184 vid, set, 0);
185 if (err)
186 return err;
187
188 /* set vid prior to syncing/unsyncing the VLAN */
189 interface->vid = vid + (set ? VLAN_N_VID : 0);
190
191 /* Update the unicast and multicast address list to add/drop VLAN */
192 __dev_uc_unsync(netdev, fm10k_uc_vlan_unsync);
193 __dev_mc_unsync(netdev, fm10k_mc_vlan_unsync);
194
195 fm10k_mbx_unlock(interface);
196
197 return 0;
198}
199
200static int fm10k_vlan_rx_add_vid(struct net_device *netdev,
201 __always_unused __be16 proto, u16 vid)
202{
203 /* update VLAN and address table based on changes */
204 return fm10k_update_vid(netdev, vid, true);
205}
206
207static int fm10k_vlan_rx_kill_vid(struct net_device *netdev,
208 __always_unused __be16 proto, u16 vid)
209{
210 /* update VLAN and address table based on changes */
211 return fm10k_update_vid(netdev, vid, false);
212}
213
214static u16 fm10k_find_next_vlan(struct fm10k_intfc *interface, u16 vid)
215{
216 struct fm10k_hw *hw = &interface->hw;
217 u16 default_vid = hw->mac.default_vid;
218 u16 vid_limit = vid < default_vid ? default_vid : VLAN_N_VID;
219
220 vid = find_next_bit(interface->active_vlans, vid_limit, ++vid);
221
222 return vid;
223}
224
225static void fm10k_clear_unused_vlans(struct fm10k_intfc *interface)
226{
227 struct fm10k_hw *hw = &interface->hw;
228 u32 vid, prev_vid;
229
230 /* loop through and find any gaps in the table */
231 for (vid = 0, prev_vid = 0;
232 prev_vid < VLAN_N_VID;
233 prev_vid = vid + 1, vid = fm10k_find_next_vlan(interface, vid)) {
234 if (prev_vid == vid)
235 continue;
236
237 /* send request to clear multiple bits at a time */
238 prev_vid += (vid - prev_vid - 1) << FM10K_VLAN_LENGTH_SHIFT;
239 hw->mac.ops.update_vlan(hw, prev_vid, 0, false);
240 }
241}
242
243static int __fm10k_uc_sync(struct net_device *dev,
244 const unsigned char *addr, bool sync)
245{
246 struct fm10k_intfc *interface = netdev_priv(dev);
247 struct fm10k_hw *hw = &interface->hw;
248 u16 vid, glort = interface->glort;
249 s32 err;
250
251 if (!is_valid_ether_addr(addr))
252 return -EADDRNOTAVAIL;
253
254 /* update table with current entries */
255 for (vid = hw->mac.default_vid ? fm10k_find_next_vlan(interface, 0) : 0;
256 vid < VLAN_N_VID;
257 vid = fm10k_find_next_vlan(interface, vid)) {
258 err = hw->mac.ops.update_uc_addr(hw, glort, addr,
259 vid, sync, 0);
260 if (err)
261 return err;
262 }
263
264 return 0;
265}
266
267static int fm10k_uc_sync(struct net_device *dev,
268 const unsigned char *addr)
269{
270 return __fm10k_uc_sync(dev, addr, true);
271}
272
273static int fm10k_uc_unsync(struct net_device *dev,
274 const unsigned char *addr)
275{
276 return __fm10k_uc_sync(dev, addr, false);
277}
278
0e7b3644
AD
279static int fm10k_set_mac(struct net_device *dev, void *p)
280{
8f5e20d4
AD
281 struct fm10k_intfc *interface = netdev_priv(dev);
282 struct fm10k_hw *hw = &interface->hw;
0e7b3644
AD
283 struct sockaddr *addr = p;
284 s32 err = 0;
285
286 if (!is_valid_ether_addr(addr->sa_data))
287 return -EADDRNOTAVAIL;
288
8f5e20d4
AD
289 if (dev->flags & IFF_UP) {
290 /* setting MAC address requires mailbox */
291 fm10k_mbx_lock(interface);
292
293 err = fm10k_uc_sync(dev, addr->sa_data);
294 if (!err)
295 fm10k_uc_unsync(dev, hw->mac.addr);
296
297 fm10k_mbx_unlock(interface);
298 }
299
0e7b3644
AD
300 if (!err) {
301 ether_addr_copy(dev->dev_addr, addr->sa_data);
8f5e20d4 302 ether_addr_copy(hw->mac.addr, addr->sa_data);
0e7b3644
AD
303 dev->addr_assign_type &= ~NET_ADDR_RANDOM;
304 }
305
8f5e20d4
AD
306 /* if we had a mailbox error suggest trying again */
307 return err ? -EAGAIN : 0;
308}
309
310static int __fm10k_mc_sync(struct net_device *dev,
311 const unsigned char *addr, bool sync)
312{
313 struct fm10k_intfc *interface = netdev_priv(dev);
314 struct fm10k_hw *hw = &interface->hw;
315 u16 vid, glort = interface->glort;
316 s32 err;
317
318 if (!is_multicast_ether_addr(addr))
319 return -EADDRNOTAVAIL;
320
321 /* update table with current entries */
322 for (vid = hw->mac.default_vid ? fm10k_find_next_vlan(interface, 0) : 0;
323 vid < VLAN_N_VID;
324 vid = fm10k_find_next_vlan(interface, vid)) {
325 err = hw->mac.ops.update_mc_addr(hw, glort, addr, vid, sync);
326 if (err)
327 return err;
328 }
329
330 return 0;
331}
332
333static int fm10k_mc_sync(struct net_device *dev,
334 const unsigned char *addr)
335{
336 return __fm10k_mc_sync(dev, addr, true);
337}
338
339static int fm10k_mc_unsync(struct net_device *dev,
340 const unsigned char *addr)
341{
342 return __fm10k_mc_sync(dev, addr, false);
0e7b3644
AD
343}
344
345static void fm10k_set_rx_mode(struct net_device *dev)
346{
8f5e20d4
AD
347 struct fm10k_intfc *interface = netdev_priv(dev);
348 struct fm10k_hw *hw = &interface->hw;
349 int xcast_mode;
350
351 /* no need to update the harwdare if we are not running */
352 if (!(dev->flags & IFF_UP))
353 return;
354
355 /* determine new mode based on flags */
356 xcast_mode = (dev->flags & IFF_PROMISC) ? FM10K_XCAST_MODE_PROMISC :
357 (dev->flags & IFF_ALLMULTI) ? FM10K_XCAST_MODE_ALLMULTI :
358 (dev->flags & (IFF_BROADCAST | IFF_MULTICAST)) ?
359 FM10K_XCAST_MODE_MULTI : FM10K_XCAST_MODE_NONE;
360
361 fm10k_mbx_lock(interface);
362
363 /* syncronize all of the addresses */
364 if (xcast_mode != FM10K_XCAST_MODE_PROMISC) {
365 __dev_uc_sync(dev, fm10k_uc_sync, fm10k_uc_unsync);
366 if (xcast_mode != FM10K_XCAST_MODE_ALLMULTI)
367 __dev_mc_sync(dev, fm10k_mc_sync, fm10k_mc_unsync);
368 }
369
370 /* if we aren't changing modes there is nothing to do */
371 if (interface->xcast_mode != xcast_mode) {
372 /* update VLAN table */
373 if (xcast_mode == FM10K_XCAST_MODE_PROMISC)
374 hw->mac.ops.update_vlan(hw, FM10K_VLAN_ALL, 0, true);
375 if (interface->xcast_mode == FM10K_XCAST_MODE_PROMISC)
376 fm10k_clear_unused_vlans(interface);
377
378 /* update xcast mode */
379 hw->mac.ops.update_xcast_mode(hw, interface->glort, xcast_mode);
380
381 /* record updated xcast mode state */
382 interface->xcast_mode = xcast_mode;
383 }
384
385 fm10k_mbx_unlock(interface);
386}
387
388void fm10k_restore_rx_state(struct fm10k_intfc *interface)
389{
390 struct net_device *netdev = interface->netdev;
391 struct fm10k_hw *hw = &interface->hw;
392 int xcast_mode;
393 u16 vid, glort;
394
395 /* record glort for this interface */
396 glort = interface->glort;
397
398 /* convert interface flags to xcast mode */
399 if (netdev->flags & IFF_PROMISC)
400 xcast_mode = FM10K_XCAST_MODE_PROMISC;
401 else if (netdev->flags & IFF_ALLMULTI)
402 xcast_mode = FM10K_XCAST_MODE_ALLMULTI;
403 else if (netdev->flags & (IFF_BROADCAST | IFF_MULTICAST))
404 xcast_mode = FM10K_XCAST_MODE_MULTI;
405 else
406 xcast_mode = FM10K_XCAST_MODE_NONE;
407
408 fm10k_mbx_lock(interface);
409
410 /* Enable logical port */
411 hw->mac.ops.update_lport_state(hw, glort, interface->glort_count, true);
412
413 /* update VLAN table */
414 hw->mac.ops.update_vlan(hw, FM10K_VLAN_ALL, 0,
415 xcast_mode == FM10K_XCAST_MODE_PROMISC);
416
417 /* Add filter for VLAN 0 */
418 hw->mac.ops.update_vlan(hw, 0, 0, true);
419
420 /* update table with current entries */
421 for (vid = hw->mac.default_vid ? fm10k_find_next_vlan(interface, 0) : 0;
422 vid < VLAN_N_VID;
423 vid = fm10k_find_next_vlan(interface, vid)) {
424 hw->mac.ops.update_vlan(hw, vid, 0, true);
425 hw->mac.ops.update_uc_addr(hw, glort, hw->mac.addr,
426 vid, true, 0);
427 }
428
429 /* syncronize all of the addresses */
430 if (xcast_mode != FM10K_XCAST_MODE_PROMISC) {
431 __dev_uc_sync(netdev, fm10k_uc_sync, fm10k_uc_unsync);
432 if (xcast_mode != FM10K_XCAST_MODE_ALLMULTI)
433 __dev_mc_sync(netdev, fm10k_mc_sync, fm10k_mc_unsync);
434 }
435
436 /* update xcast mode */
437 hw->mac.ops.update_xcast_mode(hw, glort, xcast_mode);
438
439 fm10k_mbx_unlock(interface);
440
441 /* record updated xcast mode state */
442 interface->xcast_mode = xcast_mode;
443}
444
445void fm10k_reset_rx_state(struct fm10k_intfc *interface)
446{
447 struct net_device *netdev = interface->netdev;
448 struct fm10k_hw *hw = &interface->hw;
449
450 fm10k_mbx_lock(interface);
451
452 /* clear the logical port state on lower device */
453 hw->mac.ops.update_lport_state(hw, interface->glort,
454 interface->glort_count, false);
455
456 fm10k_mbx_unlock(interface);
457
458 /* reset flags to default state */
459 interface->xcast_mode = FM10K_XCAST_MODE_NONE;
460
461 /* clear the sync flag since the lport has been dropped */
462 __dev_uc_unsync(netdev, NULL);
463 __dev_mc_unsync(netdev, NULL);
0e7b3644
AD
464}
465
466static const struct net_device_ops fm10k_netdev_ops = {
504c5eac
AD
467 .ndo_open = fm10k_open,
468 .ndo_stop = fm10k_close,
0e7b3644
AD
469 .ndo_validate_addr = eth_validate_addr,
470 .ndo_start_xmit = fm10k_xmit_frame,
471 .ndo_set_mac_address = fm10k_set_mac,
472 .ndo_change_mtu = fm10k_change_mtu,
8f5e20d4
AD
473 .ndo_vlan_rx_add_vid = fm10k_vlan_rx_add_vid,
474 .ndo_vlan_rx_kill_vid = fm10k_vlan_rx_kill_vid,
0e7b3644
AD
475 .ndo_set_rx_mode = fm10k_set_rx_mode,
476};
477
478#define DEFAULT_DEBUG_LEVEL_SHIFT 3
479
480struct net_device *fm10k_alloc_netdev(void)
481{
482 struct fm10k_intfc *interface;
483 struct net_device *dev;
484
485 dev = alloc_etherdev(sizeof(struct fm10k_intfc));
486 if (!dev)
487 return NULL;
488
489 /* set net device and ethtool ops */
490 dev->netdev_ops = &fm10k_netdev_ops;
491
492 /* configure default debug level */
493 interface = netdev_priv(dev);
494 interface->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1;
495
496 /* configure default features */
497 dev->features |= NETIF_F_SG;
498
499 /* all features defined to this point should be changeable */
500 dev->hw_features |= dev->features;
501
502 /* configure VLAN features */
503 dev->vlan_features |= dev->features;
504
505 /* configure tunnel offloads */
506 dev->hw_enc_features = NETIF_F_SG;
507
8f5e20d4
AD
508 /* we want to leave these both on as we cannot disable VLAN tag
509 * insertion or stripping on the hardware since it is contained
510 * in the FTAG and not in the frame itself.
511 */
512 dev->features |= NETIF_F_HW_VLAN_CTAG_TX |
513 NETIF_F_HW_VLAN_CTAG_RX |
514 NETIF_F_HW_VLAN_CTAG_FILTER;
515
516 dev->priv_flags |= IFF_UNICAST_FLT;
517
0e7b3644
AD
518 return dev;
519}
This page took 0.043687 seconds and 5 git commands to generate.