blob: 34166641f207c52571546b7d0855ce823ce0f7c9 [file] [log] [blame]
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001/*
2 * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 */
33
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/netdevice.h>
37#include <linux/etherdevice.h>
38#include <linux/ip.h>
39#include <linux/tcp.h>
40#include <linux/if_arp.h>
41#include <linux/if_vlan.h>
42#include <linux/ethtool.h>
43#include <net/tcp.h>
44
45#include <net/inet_common.h>
46#include <linux/inet.h>
47
48#include "nes.h"
49
50static struct nic_qp_map nic_qp_mapping_0[] = {
51 {16,0,0,1},{24,4,0,0},{28,8,0,0},{32,12,0,0},
52 {20,2,2,1},{26,6,2,0},{30,10,2,0},{34,14,2,0},
53 {18,1,1,1},{25,5,1,0},{29,9,1,0},{33,13,1,0},
54 {22,3,3,1},{27,7,3,0},{31,11,3,0},{35,15,3,0}
55};
56
57static struct nic_qp_map nic_qp_mapping_1[] = {
58 {18,1,1,1},{25,5,1,0},{29,9,1,0},{33,13,1,0},
59 {22,3,3,1},{27,7,3,0},{31,11,3,0},{35,15,3,0}
60};
61
62static struct nic_qp_map nic_qp_mapping_2[] = {
63 {20,2,2,1},{26,6,2,0},{30,10,2,0},{34,14,2,0}
64};
65
66static struct nic_qp_map nic_qp_mapping_3[] = {
67 {22,3,3,1},{27,7,3,0},{31,11,3,0},{35,15,3,0}
68};
69
70static struct nic_qp_map nic_qp_mapping_4[] = {
71 {28,8,0,0},{32,12,0,0}
72};
73
74static struct nic_qp_map nic_qp_mapping_5[] = {
75 {29,9,1,0},{33,13,1,0}
76};
77
78static struct nic_qp_map nic_qp_mapping_6[] = {
79 {30,10,2,0},{34,14,2,0}
80};
81
82static struct nic_qp_map nic_qp_mapping_7[] = {
83 {31,11,3,0},{35,15,3,0}
84};
85
86static struct nic_qp_map *nic_qp_mapping_per_function[] = {
87 nic_qp_mapping_0, nic_qp_mapping_1, nic_qp_mapping_2, nic_qp_mapping_3,
88 nic_qp_mapping_4, nic_qp_mapping_5, nic_qp_mapping_6, nic_qp_mapping_7
89};
90
91static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
92 | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
93static int debug = -1;
94
95
96static int nes_netdev_open(struct net_device *);
97static int nes_netdev_stop(struct net_device *);
98static int nes_netdev_start_xmit(struct sk_buff *, struct net_device *);
99static struct net_device_stats *nes_netdev_get_stats(struct net_device *);
100static void nes_netdev_tx_timeout(struct net_device *);
101static int nes_netdev_set_mac_address(struct net_device *, void *);
102static int nes_netdev_change_mtu(struct net_device *, int);
103
104/**
105 * nes_netdev_poll
106 */
107static int nes_netdev_poll(struct napi_struct *napi, int budget)
108{
109 struct nes_vnic *nesvnic = container_of(napi, struct nes_vnic, napi);
110 struct net_device *netdev = nesvnic->netdev;
111 struct nes_device *nesdev = nesvnic->nesdev;
112 struct nes_hw_nic_cq *nescq = &nesvnic->nic_cq;
113
114 nesvnic->budget = budget;
115 nescq->cqes_pending = 0;
116 nescq->rx_cqes_completed = 0;
117 nescq->cqe_allocs_pending = 0;
118 nescq->rx_pkts_indicated = 0;
119
120 nes_nic_ce_handler(nesdev, nescq);
121
122 if (nescq->cqes_pending == 0) {
123 netif_rx_complete(netdev, napi);
124 /* clear out completed cqes and arm */
125 nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
126 nescq->cq_number | (nescq->cqe_allocs_pending << 16));
127 nes_read32(nesdev->regs+NES_CQE_ALLOC);
128 } else {
129 /* clear out completed cqes but don't arm */
130 nes_write32(nesdev->regs+NES_CQE_ALLOC,
131 nescq->cq_number | (nescq->cqe_allocs_pending << 16));
132 nes_debug(NES_DBG_NETDEV, "%s: exiting with work pending\n",
133 nesvnic->netdev->name);
134 }
135 return nescq->rx_pkts_indicated;
136}
137
138
139/**
140 * nes_netdev_open - Activate the network interface; ifconfig
141 * ethx up.
142 */
143static int nes_netdev_open(struct net_device *netdev)
144{
145 u32 macaddr_low;
146 u16 macaddr_high;
147 struct nes_vnic *nesvnic = netdev_priv(netdev);
148 struct nes_device *nesdev = nesvnic->nesdev;
149 int ret;
150 int i;
Glenn Streiff11e07042008-02-15 11:41:27 -0600151 struct nes_vnic *first_nesvnic = NULL;
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800152 u32 nic_active_bit;
153 u32 nic_active;
Glenn Streiff11e07042008-02-15 11:41:27 -0600154 struct list_head *list_pos, *list_temp;
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800155
156 assert(nesdev != NULL);
157
Glenn Streiff11e07042008-02-15 11:41:27 -0600158 if (nesvnic->netdev_open == 1)
159 return 0;
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800160
161 if (netif_msg_ifup(nesvnic))
162 printk(KERN_INFO PFX "%s: enabling interface\n", netdev->name);
163
164 ret = nes_init_nic_qp(nesdev, netdev);
165 if (ret) {
166 return ret;
167 }
168
169 netif_carrier_off(netdev);
170 netif_stop_queue(netdev);
171
172 if ((!nesvnic->of_device_registered) && (nesvnic->rdma_enabled)) {
173 nesvnic->nesibdev = nes_init_ofa_device(netdev);
174 if (nesvnic->nesibdev == NULL) {
175 printk(KERN_ERR PFX "%s: nesvnic->nesibdev alloc failed", netdev->name);
176 } else {
177 nesvnic->nesibdev->nesvnic = nesvnic;
178 ret = nes_register_ofa_device(nesvnic->nesibdev);
179 if (ret) {
180 printk(KERN_ERR PFX "%s: Unable to register RDMA device, ret = %d\n",
181 netdev->name, ret);
182 }
183 }
184 }
185 /* Set packet filters */
186 nic_active_bit = 1 << nesvnic->nic_index;
187 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_ACTIVE);
188 nic_active |= nic_active_bit;
189 nes_write_indexed(nesdev, NES_IDX_NIC_ACTIVE, nic_active);
190 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ENABLE);
191 nic_active |= nic_active_bit;
192 nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ENABLE, nic_active);
193 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON);
194 nic_active |= nic_active_bit;
195 nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active);
196
197 macaddr_high = ((u16)netdev->dev_addr[0]) << 8;
198 macaddr_high += (u16)netdev->dev_addr[1];
199 macaddr_low = ((u32)netdev->dev_addr[2]) << 24;
200 macaddr_low += ((u32)netdev->dev_addr[3]) << 16;
201 macaddr_low += ((u32)netdev->dev_addr[4]) << 8;
202 macaddr_low += (u32)netdev->dev_addr[5];
203
204 /* Program the various MAC regs */
205 for (i = 0; i < NES_MAX_PORT_COUNT; i++) {
206 if (nesvnic->qp_nic_index[i] == 0xf) {
207 break;
208 }
209 nes_debug(NES_DBG_NETDEV, "i=%d, perfect filter table index= %d, PERF FILTER LOW"
210 " (Addr:%08X) = %08X, HIGH = %08X.\n",
211 i, nesvnic->qp_nic_index[i],
212 NES_IDX_PERFECT_FILTER_LOW+((nesvnic->perfect_filter_index + i) * 8),
213 macaddr_low,
214 (u32)macaddr_high | NES_MAC_ADDR_VALID |
215 ((((u32)nesvnic->nic_index) << 16)));
216 nes_write_indexed(nesdev,
217 NES_IDX_PERFECT_FILTER_LOW + (nesvnic->qp_nic_index[i] * 8),
218 macaddr_low);
219 nes_write_indexed(nesdev,
220 NES_IDX_PERFECT_FILTER_HIGH + (nesvnic->qp_nic_index[i] * 8),
221 (u32)macaddr_high | NES_MAC_ADDR_VALID |
222 ((((u32)nesvnic->nic_index) << 16)));
223 }
224
225
226 nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
227 nesvnic->nic_cq.cq_number);
228 nes_read32(nesdev->regs+NES_CQE_ALLOC);
Glenn Streiff11e07042008-02-15 11:41:27 -0600229 list_for_each_safe(list_pos, list_temp, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]) {
230 first_nesvnic = container_of(list_pos, struct nes_vnic, list);
231 if (first_nesvnic->netdev_open == 1)
232 break;
233 }
234 if (first_nesvnic->netdev_open == 0) {
235 nes_debug(NES_DBG_INIT, "Setting up MAC interrupt mask.\n");
236 nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK + (0x200 * nesdev->mac_index),
237 ~(NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT |
238 NES_MAC_INT_TX_UNDERFLOW | NES_MAC_INT_TX_ERROR));
239 first_nesvnic = nesvnic;
240 }
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800241 if (first_nesvnic->linkup) {
242 /* Enable network packets */
243 nesvnic->linkup = 1;
244 netif_start_queue(netdev);
245 netif_carrier_on(netdev);
246 }
247 napi_enable(&nesvnic->napi);
248 nesvnic->netdev_open = 1;
249
250 return 0;
251}
252
253
254/**
255 * nes_netdev_stop
256 */
257static int nes_netdev_stop(struct net_device *netdev)
258{
259 struct nes_vnic *nesvnic = netdev_priv(netdev);
260 struct nes_device *nesdev = nesvnic->nesdev;
261 u32 nic_active_mask;
262 u32 nic_active;
Glenn Streiff11e07042008-02-15 11:41:27 -0600263 struct nes_vnic *first_nesvnic = NULL;
264 struct list_head *list_pos, *list_temp;
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800265
266 nes_debug(NES_DBG_SHUTDOWN, "nesvnic=%p, nesdev=%p, netdev=%p %s\n",
267 nesvnic, nesdev, netdev, netdev->name);
268 if (nesvnic->netdev_open == 0)
269 return 0;
270
271 if (netif_msg_ifdown(nesvnic))
272 printk(KERN_INFO PFX "%s: disabling interface\n", netdev->name);
273
274 /* Disable network packets */
275 napi_disable(&nesvnic->napi);
276 netif_stop_queue(netdev);
Glenn Streiff11e07042008-02-15 11:41:27 -0600277 list_for_each_safe(list_pos, list_temp, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]) {
278 first_nesvnic = container_of(list_pos, struct nes_vnic, list);
279 if ((first_nesvnic->netdev_open == 1) && (first_nesvnic != nesvnic))
280 break;
281 }
282
283 if (first_nesvnic->netdev_open == 0)
284 nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK+(0x200*nesdev->mac_index), 0xffffffff);
285 else if ((first_nesvnic != nesvnic) &&
286 (PCI_FUNC(first_nesvnic->nesdev->pcidev->devfn) != PCI_FUNC(nesvnic->nesdev->pcidev->devfn))) {
287 nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK + (0x200 * nesdev->mac_index), 0xffffffff);
288 nes_write_indexed(first_nesvnic->nesdev, NES_IDX_MAC_INT_MASK + (0x200 * first_nesvnic->nesdev->mac_index),
289 ~(NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT |
290 NES_MAC_INT_TX_UNDERFLOW | NES_MAC_INT_TX_ERROR));
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800291 }
292
293 nic_active_mask = ~((u32)(1 << nesvnic->nic_index));
294 nes_write_indexed(nesdev, NES_IDX_PERFECT_FILTER_HIGH+
295 (nesvnic->perfect_filter_index*8), 0);
296 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_ACTIVE);
297 nic_active &= nic_active_mask;
298 nes_write_indexed(nesdev, NES_IDX_NIC_ACTIVE, nic_active);
299 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL);
300 nic_active &= nic_active_mask;
301 nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active);
302 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ENABLE);
303 nic_active &= nic_active_mask;
304 nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ENABLE, nic_active);
305 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL);
306 nic_active &= nic_active_mask;
307 nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
308 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON);
309 nic_active &= nic_active_mask;
310 nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active);
311
312
313 if (nesvnic->of_device_registered) {
314 nes_destroy_ofa_device(nesvnic->nesibdev);
315 nesvnic->nesibdev = NULL;
316 nesvnic->of_device_registered = 0;
317 }
318 nes_destroy_nic_qp(nesvnic);
319
320 nesvnic->netdev_open = 0;
321
322 return 0;
323}
324
325
326/**
327 * nes_nic_send
328 */
329static int nes_nic_send(struct sk_buff *skb, struct net_device *netdev)
330{
331 struct nes_vnic *nesvnic = netdev_priv(netdev);
332 struct nes_device *nesdev = nesvnic->nesdev;
333 struct nes_hw_nic *nesnic = &nesvnic->nic;
334 struct nes_hw_nic_sq_wqe *nic_sqe;
335 struct tcphdr *tcph;
336 __le16 *wqe_fragment_length;
337 u32 wqe_misc;
338 u16 wqe_fragment_index = 1; /* first fragment (0) is used by copy buffer */
339 u16 skb_fragment_index;
340 dma_addr_t bus_address;
341
342 nic_sqe = &nesnic->sq_vbase[nesnic->sq_head];
343 wqe_fragment_length = (__le16 *)&nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX];
344
345 /* setup the VLAN tag if present */
346 if (vlan_tx_tag_present(skb)) {
347 nes_debug(NES_DBG_NIC_TX, "%s: VLAN packet to send... VLAN = %08X\n",
348 netdev->name, vlan_tx_tag_get(skb));
349 wqe_misc = NES_NIC_SQ_WQE_TAGVALUE_ENABLE;
350 wqe_fragment_length[0] = (__force __le16) vlan_tx_tag_get(skb);
351 } else
352 wqe_misc = 0;
353
354 /* bump past the vlan tag */
355 wqe_fragment_length++;
356 /* wqe_fragment_address = (u64 *)&nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX]; */
357
358 if (skb->ip_summed == CHECKSUM_PARTIAL) {
359 tcph = tcp_hdr(skb);
360 if (1) {
361 if (skb_is_gso(skb)) {
362 /* nes_debug(NES_DBG_NIC_TX, "%s: TSO request... seg size = %u\n",
363 netdev->name, skb_is_gso(skb)); */
364 wqe_misc |= NES_NIC_SQ_WQE_LSO_ENABLE |
365 NES_NIC_SQ_WQE_COMPLETION | (u16)skb_is_gso(skb);
366 set_wqe_32bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_LSO_INFO_IDX,
367 ((u32)tcph->doff) |
368 (((u32)(((unsigned char *)tcph) - skb->data)) << 4));
369 } else {
370 wqe_misc |= NES_NIC_SQ_WQE_COMPLETION;
371 }
372 }
373 } else { /* CHECKSUM_HW */
374 wqe_misc |= NES_NIC_SQ_WQE_DISABLE_CHKSUM | NES_NIC_SQ_WQE_COMPLETION;
375 }
376
377 set_wqe_32bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_TOTAL_LENGTH_IDX,
378 skb->len);
379 memcpy(&nesnic->first_frag_vbase[nesnic->sq_head].buffer,
380 skb->data, min(((unsigned int)NES_FIRST_FRAG_SIZE), skb_headlen(skb)));
381 wqe_fragment_length[0] = cpu_to_le16(min(((unsigned int)NES_FIRST_FRAG_SIZE),
382 skb_headlen(skb)));
383 wqe_fragment_length[1] = 0;
384 if (skb_headlen(skb) > NES_FIRST_FRAG_SIZE) {
385 if ((skb_shinfo(skb)->nr_frags + 1) > 4) {
386 nes_debug(NES_DBG_NIC_TX, "%s: Packet with %u fragments not sent, skb_headlen=%u\n",
387 netdev->name, skb_shinfo(skb)->nr_frags + 2, skb_headlen(skb));
388 kfree_skb(skb);
389 nesvnic->tx_sw_dropped++;
390 return NETDEV_TX_LOCKED;
391 }
392 set_bit(nesnic->sq_head, nesnic->first_frag_overflow);
393 bus_address = pci_map_single(nesdev->pcidev, skb->data + NES_FIRST_FRAG_SIZE,
394 skb_headlen(skb) - NES_FIRST_FRAG_SIZE, PCI_DMA_TODEVICE);
395 wqe_fragment_length[wqe_fragment_index++] =
396 cpu_to_le16(skb_headlen(skb) - NES_FIRST_FRAG_SIZE);
397 wqe_fragment_length[wqe_fragment_index] = 0;
398 set_wqe_64bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_FRAG1_LOW_IDX,
399 ((u64)(bus_address)));
400 nesnic->tx_skb[nesnic->sq_head] = skb;
401 }
402
403 if (skb_headlen(skb) == skb->len) {
404 if (skb_headlen(skb) <= NES_FIRST_FRAG_SIZE) {
405 nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_2_1_IDX] = 0;
406 nesnic->tx_skb[nesnic->sq_head] = NULL;
407 dev_kfree_skb(skb);
408 }
409 } else {
410 /* Deal with Fragments */
411 nesnic->tx_skb[nesnic->sq_head] = skb;
412 for (skb_fragment_index = 0; skb_fragment_index < skb_shinfo(skb)->nr_frags;
413 skb_fragment_index++) {
414 bus_address = pci_map_page( nesdev->pcidev,
415 skb_shinfo(skb)->frags[skb_fragment_index].page,
416 skb_shinfo(skb)->frags[skb_fragment_index].page_offset,
417 skb_shinfo(skb)->frags[skb_fragment_index].size,
418 PCI_DMA_TODEVICE);
419 wqe_fragment_length[wqe_fragment_index] =
420 cpu_to_le16(skb_shinfo(skb)->frags[skb_fragment_index].size);
421 set_wqe_64bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_FRAG0_LOW_IDX+(2*wqe_fragment_index),
422 bus_address);
423 wqe_fragment_index++;
424 if (wqe_fragment_index < 5)
425 wqe_fragment_length[wqe_fragment_index] = 0;
426 }
427 }
428
429 set_wqe_32bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_MISC_IDX, wqe_misc);
430 nesnic->sq_head++;
431 nesnic->sq_head &= nesnic->sq_size - 1;
432
433 return NETDEV_TX_OK;
434}
435
436
437/**
438 * nes_netdev_start_xmit
439 */
440static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
441{
442 struct nes_vnic *nesvnic = netdev_priv(netdev);
443 struct nes_device *nesdev = nesvnic->nesdev;
444 struct nes_hw_nic *nesnic = &nesvnic->nic;
445 struct nes_hw_nic_sq_wqe *nic_sqe;
446 struct tcphdr *tcph;
447 /* struct udphdr *udph; */
448#define NES_MAX_TSO_FRAGS 18
449 /* 64K segment plus overflow on each side */
450 dma_addr_t tso_bus_address[NES_MAX_TSO_FRAGS];
451 dma_addr_t bus_address;
452 u32 tso_frag_index;
453 u32 tso_frag_count;
454 u32 tso_wqe_length;
455 u32 curr_tcp_seq;
456 u32 wqe_count=1;
457 u32 send_rc;
458 struct iphdr *iph;
459 unsigned long flags;
460 __le16 *wqe_fragment_length;
461 u32 nr_frags;
462 u32 original_first_length;
463// u64 *wqe_fragment_address;
464 /* first fragment (0) is used by copy buffer */
465 u16 wqe_fragment_index=1;
466 u16 hoffset;
467 u16 nhoffset;
468 u16 wqes_needed;
469 u16 wqes_available;
470 u32 old_head;
471 u32 wqe_misc;
472
473 /* nes_debug(NES_DBG_NIC_TX, "%s Request to tx NIC packet length %u, headlen %u,"
474 " (%u frags), tso_size=%u\n",
475 netdev->name, skb->len, skb_headlen(skb),
476 skb_shinfo(skb)->nr_frags, skb_is_gso(skb));
477 */
478
479 if (!netif_carrier_ok(netdev))
480 return NETDEV_TX_OK;
481
482 if (netif_queue_stopped(netdev))
483 return NETDEV_TX_BUSY;
484
485 local_irq_save(flags);
486 if (!spin_trylock(&nesnic->sq_lock)) {
487 local_irq_restore(flags);
488 nesvnic->sq_locked++;
489 return NETDEV_TX_LOCKED;
490 }
491
492 /* Check if SQ is full */
493 if ((((nesnic->sq_tail+(nesnic->sq_size*2))-nesnic->sq_head) & (nesnic->sq_size - 1)) == 1) {
494 if (!netif_queue_stopped(netdev)) {
495 netif_stop_queue(netdev);
496 barrier();
497 if ((((((volatile u16)nesnic->sq_tail)+(nesnic->sq_size*2))-nesnic->sq_head) & (nesnic->sq_size - 1)) != 1) {
498 netif_start_queue(netdev);
499 goto sq_no_longer_full;
500 }
501 }
502 nesvnic->sq_full++;
503 spin_unlock_irqrestore(&nesnic->sq_lock, flags);
504 return NETDEV_TX_BUSY;
505 }
506
507sq_no_longer_full:
508 nr_frags = skb_shinfo(skb)->nr_frags;
509 if (skb_headlen(skb) > NES_FIRST_FRAG_SIZE) {
510 nr_frags++;
511 }
512 /* Check if too many fragments */
513 if (unlikely((nr_frags > 4))) {
514 if (skb_is_gso(skb)) {
515 nesvnic->segmented_tso_requests++;
516 nesvnic->tso_requests++;
517 old_head = nesnic->sq_head;
518 /* Basically 4 fragments available per WQE with extended fragments */
519 wqes_needed = nr_frags >> 2;
520 wqes_needed += (nr_frags&3)?1:0;
521 wqes_available = (((nesnic->sq_tail+nesnic->sq_size)-nesnic->sq_head) - 1) &
522 (nesnic->sq_size - 1);
523
524 if (unlikely(wqes_needed > wqes_available)) {
525 if (!netif_queue_stopped(netdev)) {
526 netif_stop_queue(netdev);
527 barrier();
528 wqes_available = (((((volatile u16)nesnic->sq_tail)+nesnic->sq_size)-nesnic->sq_head) - 1) &
529 (nesnic->sq_size - 1);
530 if (wqes_needed <= wqes_available) {
531 netif_start_queue(netdev);
532 goto tso_sq_no_longer_full;
533 }
534 }
535 nesvnic->sq_full++;
536 spin_unlock_irqrestore(&nesnic->sq_lock, flags);
537 nes_debug(NES_DBG_NIC_TX, "%s: HNIC SQ full- TSO request has too many frags!\n",
538 netdev->name);
539 return NETDEV_TX_BUSY;
540 }
541tso_sq_no_longer_full:
542 /* Map all the buffers */
543 for (tso_frag_count=0; tso_frag_count < skb_shinfo(skb)->nr_frags;
544 tso_frag_count++) {
545 tso_bus_address[tso_frag_count] = pci_map_page( nesdev->pcidev,
546 skb_shinfo(skb)->frags[tso_frag_count].page,
547 skb_shinfo(skb)->frags[tso_frag_count].page_offset,
548 skb_shinfo(skb)->frags[tso_frag_count].size,
549 PCI_DMA_TODEVICE);
550 }
551
552 tso_frag_index = 0;
553 curr_tcp_seq = ntohl(tcp_hdr(skb)->seq);
554 hoffset = skb_transport_header(skb) - skb->data;
555 nhoffset = skb_network_header(skb) - skb->data;
556 original_first_length = hoffset + ((((struct tcphdr *)skb_transport_header(skb))->doff)<<2);
557
558 for (wqe_count=0; wqe_count<((u32)wqes_needed); wqe_count++) {
559 tso_wqe_length = 0;
560 nic_sqe = &nesnic->sq_vbase[nesnic->sq_head];
561 wqe_fragment_length =
562 (__le16 *)&nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX];
563 /* setup the VLAN tag if present */
564 if (vlan_tx_tag_present(skb)) {
565 nes_debug(NES_DBG_NIC_TX, "%s: VLAN packet to send... VLAN = %08X\n",
566 netdev->name, vlan_tx_tag_get(skb) );
567 wqe_misc = NES_NIC_SQ_WQE_TAGVALUE_ENABLE;
568 wqe_fragment_length[0] = (__force __le16) vlan_tx_tag_get(skb);
569 } else
570 wqe_misc = 0;
571
572 /* bump past the vlan tag */
573 wqe_fragment_length++;
574
575 /* Assumes header totally fits in allocated buffer and is in first fragment */
576 if (original_first_length > NES_FIRST_FRAG_SIZE) {
577 nes_debug(NES_DBG_NIC_TX, "ERROR: SKB header too big, headlen=%u, FIRST_FRAG_SIZE=%u\n",
578 original_first_length, NES_FIRST_FRAG_SIZE);
579 nes_debug(NES_DBG_NIC_TX, "%s Request to tx NIC packet length %u, headlen %u,"
580 " (%u frags), tso_size=%u\n",
581 netdev->name,
582 skb->len, skb_headlen(skb),
583 skb_shinfo(skb)->nr_frags, skb_is_gso(skb));
584 }
585 memcpy(&nesnic->first_frag_vbase[nesnic->sq_head].buffer,
586 skb->data, min(((unsigned int)NES_FIRST_FRAG_SIZE),
587 original_first_length));
588 iph = (struct iphdr *)
589 (&nesnic->first_frag_vbase[nesnic->sq_head].buffer[nhoffset]);
590 tcph = (struct tcphdr *)
591 (&nesnic->first_frag_vbase[nesnic->sq_head].buffer[hoffset]);
592 if ((wqe_count+1)!=(u32)wqes_needed) {
593 tcph->fin = 0;
594 tcph->psh = 0;
595 tcph->rst = 0;
596 tcph->urg = 0;
597 }
598 if (wqe_count) {
599 tcph->syn = 0;
600 }
601 tcph->seq = htonl(curr_tcp_seq);
602 wqe_fragment_length[0] = cpu_to_le16(min(((unsigned int)NES_FIRST_FRAG_SIZE),
603 original_first_length));
604
605 wqe_fragment_index = 1;
606 if ((wqe_count==0) && (skb_headlen(skb) > original_first_length)) {
607 set_bit(nesnic->sq_head, nesnic->first_frag_overflow);
608 bus_address = pci_map_single(nesdev->pcidev, skb->data + original_first_length,
609 skb_headlen(skb) - original_first_length, PCI_DMA_TODEVICE);
610 wqe_fragment_length[wqe_fragment_index++] =
611 cpu_to_le16(skb_headlen(skb) - original_first_length);
612 wqe_fragment_length[wqe_fragment_index] = 0;
613 set_wqe_64bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_FRAG1_LOW_IDX,
614 bus_address);
615 }
616 while (wqe_fragment_index < 5) {
617 wqe_fragment_length[wqe_fragment_index] =
618 cpu_to_le16(skb_shinfo(skb)->frags[tso_frag_index].size);
619 set_wqe_64bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_FRAG0_LOW_IDX+(2*wqe_fragment_index),
620 (u64)tso_bus_address[tso_frag_index]);
621 wqe_fragment_index++;
622 tso_wqe_length += skb_shinfo(skb)->frags[tso_frag_index++].size;
623 if (wqe_fragment_index < 5)
624 wqe_fragment_length[wqe_fragment_index] = 0;
625 if (tso_frag_index == tso_frag_count)
626 break;
627 }
628 if ((wqe_count+1) == (u32)wqes_needed) {
629 nesnic->tx_skb[nesnic->sq_head] = skb;
630 } else {
631 nesnic->tx_skb[nesnic->sq_head] = NULL;
632 }
633 wqe_misc |= NES_NIC_SQ_WQE_COMPLETION | (u16)skb_is_gso(skb);
634 if ((tso_wqe_length + original_first_length) > skb_is_gso(skb)) {
635 wqe_misc |= NES_NIC_SQ_WQE_LSO_ENABLE;
636 } else {
637 iph->tot_len = htons(tso_wqe_length + original_first_length - nhoffset);
638 }
639
640 set_wqe_32bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_MISC_IDX,
641 wqe_misc);
642 set_wqe_32bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_LSO_INFO_IDX,
643 ((u32)tcph->doff) | (((u32)hoffset) << 4));
644
645 set_wqe_32bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_TOTAL_LENGTH_IDX,
646 tso_wqe_length + original_first_length);
647 curr_tcp_seq += tso_wqe_length;
648 nesnic->sq_head++;
649 nesnic->sq_head &= nesnic->sq_size-1;
650 }
651 } else {
652 nesvnic->linearized_skbs++;
653 hoffset = skb_transport_header(skb) - skb->data;
654 nhoffset = skb_network_header(skb) - skb->data;
655 skb_linearize(skb);
656 skb_set_transport_header(skb, hoffset);
657 skb_set_network_header(skb, nhoffset);
658 send_rc = nes_nic_send(skb, netdev);
659 if (send_rc != NETDEV_TX_OK) {
660 spin_unlock_irqrestore(&nesnic->sq_lock, flags);
661 return NETDEV_TX_OK;
662 }
663 }
664 } else {
665 send_rc = nes_nic_send(skb, netdev);
666 if (send_rc != NETDEV_TX_OK) {
667 spin_unlock_irqrestore(&nesnic->sq_lock, flags);
668 return NETDEV_TX_OK;
669 }
670 }
671
672 barrier();
673
674 if (wqe_count)
675 nes_write32(nesdev->regs+NES_WQE_ALLOC,
676 (wqe_count << 24) | (1 << 23) | nesvnic->nic.qp_id);
677
678 netdev->trans_start = jiffies;
679 spin_unlock_irqrestore(&nesnic->sq_lock, flags);
680
681 return NETDEV_TX_OK;
682}
683
684
685/**
686 * nes_netdev_get_stats
687 */
688static struct net_device_stats *nes_netdev_get_stats(struct net_device *netdev)
689{
690 struct nes_vnic *nesvnic = netdev_priv(netdev);
691 struct nes_device *nesdev = nesvnic->nesdev;
692 u64 u64temp;
693 u32 u32temp;
694
695 u32temp = nes_read_indexed(nesdev,
696 NES_IDX_ENDNODE0_NSTAT_RX_DISCARD + (nesvnic->nic_index*0x200));
697 nesvnic->netstats.rx_dropped += u32temp;
698 nesvnic->endnode_nstat_rx_discard += u32temp;
699
700 u64temp = (u64)nes_read_indexed(nesdev,
701 NES_IDX_ENDNODE0_NSTAT_RX_OCTETS_LO + (nesvnic->nic_index*0x200));
702 u64temp += ((u64)nes_read_indexed(nesdev,
703 NES_IDX_ENDNODE0_NSTAT_RX_OCTETS_HI + (nesvnic->nic_index*0x200))) << 32;
704
705 nesvnic->endnode_nstat_rx_octets += u64temp;
706 nesvnic->netstats.rx_bytes += u64temp;
707
708 u64temp = (u64)nes_read_indexed(nesdev,
709 NES_IDX_ENDNODE0_NSTAT_RX_FRAMES_LO + (nesvnic->nic_index*0x200));
710 u64temp += ((u64)nes_read_indexed(nesdev,
711 NES_IDX_ENDNODE0_NSTAT_RX_FRAMES_HI + (nesvnic->nic_index*0x200))) << 32;
712
713 nesvnic->endnode_nstat_rx_frames += u64temp;
714 nesvnic->netstats.rx_packets += u64temp;
715
716 u64temp = (u64)nes_read_indexed(nesdev,
717 NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_LO + (nesvnic->nic_index*0x200));
718 u64temp += ((u64)nes_read_indexed(nesdev,
719 NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_HI + (nesvnic->nic_index*0x200))) << 32;
720
721 nesvnic->endnode_nstat_tx_octets += u64temp;
722 nesvnic->netstats.tx_bytes += u64temp;
723
724 u64temp = (u64)nes_read_indexed(nesdev,
725 NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_LO + (nesvnic->nic_index*0x200));
726 u64temp += ((u64)nes_read_indexed(nesdev,
727 NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_HI + (nesvnic->nic_index*0x200))) << 32;
728
729 nesvnic->endnode_nstat_tx_frames += u64temp;
730 nesvnic->netstats.tx_packets += u64temp;
731
732 u32temp = nes_read_indexed(nesdev,
733 NES_IDX_MAC_RX_SHORT_FRAMES + (nesvnic->nesdev->mac_index*0x200));
734 nesvnic->netstats.rx_dropped += u32temp;
735 nesvnic->nesdev->mac_rx_errors += u32temp;
736 nesvnic->nesdev->mac_rx_short_frames += u32temp;
737
738 u32temp = nes_read_indexed(nesdev,
739 NES_IDX_MAC_RX_OVERSIZED_FRAMES + (nesvnic->nesdev->mac_index*0x200));
740 nesvnic->netstats.rx_dropped += u32temp;
741 nesvnic->nesdev->mac_rx_errors += u32temp;
742 nesvnic->nesdev->mac_rx_oversized_frames += u32temp;
743
744 u32temp = nes_read_indexed(nesdev,
745 NES_IDX_MAC_RX_JABBER_FRAMES + (nesvnic->nesdev->mac_index*0x200));
746 nesvnic->netstats.rx_dropped += u32temp;
747 nesvnic->nesdev->mac_rx_errors += u32temp;
748 nesvnic->nesdev->mac_rx_jabber_frames += u32temp;
749
750 u32temp = nes_read_indexed(nesdev,
751 NES_IDX_MAC_RX_SYMBOL_ERR_FRAMES + (nesvnic->nesdev->mac_index*0x200));
752 nesvnic->netstats.rx_dropped += u32temp;
753 nesvnic->nesdev->mac_rx_errors += u32temp;
754 nesvnic->nesdev->mac_rx_symbol_err_frames += u32temp;
755
756 u32temp = nes_read_indexed(nesdev,
757 NES_IDX_MAC_RX_LENGTH_ERR_FRAMES + (nesvnic->nesdev->mac_index*0x200));
758 nesvnic->netstats.rx_length_errors += u32temp;
759 nesvnic->nesdev->mac_rx_errors += u32temp;
760
761 u32temp = nes_read_indexed(nesdev,
762 NES_IDX_MAC_RX_CRC_ERR_FRAMES + (nesvnic->nesdev->mac_index*0x200));
763 nesvnic->nesdev->mac_rx_errors += u32temp;
764 nesvnic->nesdev->mac_rx_crc_errors += u32temp;
765 nesvnic->netstats.rx_crc_errors += u32temp;
766
767 u32temp = nes_read_indexed(nesdev,
768 NES_IDX_MAC_TX_ERRORS + (nesvnic->nesdev->mac_index*0x200));
769 nesvnic->nesdev->mac_tx_errors += u32temp;
770 nesvnic->netstats.tx_errors += u32temp;
771
772 return &nesvnic->netstats;
773}
774
775
776/**
777 * nes_netdev_tx_timeout
778 */
779static void nes_netdev_tx_timeout(struct net_device *netdev)
780{
781 struct nes_vnic *nesvnic = netdev_priv(netdev);
782
783 if (netif_msg_timer(nesvnic))
784 nes_debug(NES_DBG_NIC_TX, "%s: tx timeout\n", netdev->name);
785}
786
787
788/**
789 * nes_netdev_set_mac_address
790 */
791static int nes_netdev_set_mac_address(struct net_device *netdev, void *p)
792{
793 struct nes_vnic *nesvnic = netdev_priv(netdev);
794 struct nes_device *nesdev = nesvnic->nesdev;
795 struct sockaddr *mac_addr = p;
796 int i;
797 u32 macaddr_low;
798 u16 macaddr_high;
799
800 if (!is_valid_ether_addr(mac_addr->sa_data))
801 return -EADDRNOTAVAIL;
802
803 memcpy(netdev->dev_addr, mac_addr->sa_data, netdev->addr_len);
804 printk(PFX "%s: Address length = %d, Address = %02X%02X%02X%02X%02X%02X..\n",
Harvey Harrison33718362008-04-16 21:01:10 -0700805 __func__, netdev->addr_len,
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800806 mac_addr->sa_data[0], mac_addr->sa_data[1],
807 mac_addr->sa_data[2], mac_addr->sa_data[3],
808 mac_addr->sa_data[4], mac_addr->sa_data[5]);
809 macaddr_high = ((u16)netdev->dev_addr[0]) << 8;
810 macaddr_high += (u16)netdev->dev_addr[1];
811 macaddr_low = ((u32)netdev->dev_addr[2]) << 24;
812 macaddr_low += ((u32)netdev->dev_addr[3]) << 16;
813 macaddr_low += ((u32)netdev->dev_addr[4]) << 8;
814 macaddr_low += (u32)netdev->dev_addr[5];
815
816 for (i = 0; i < NES_MAX_PORT_COUNT; i++) {
817 if (nesvnic->qp_nic_index[i] == 0xf) {
818 break;
819 }
820 nes_write_indexed(nesdev,
821 NES_IDX_PERFECT_FILTER_LOW + (nesvnic->qp_nic_index[i] * 8),
822 macaddr_low);
823 nes_write_indexed(nesdev,
824 NES_IDX_PERFECT_FILTER_HIGH + (nesvnic->qp_nic_index[i] * 8),
825 (u32)macaddr_high | NES_MAC_ADDR_VALID |
826 ((((u32)nesvnic->nic_index) << 16)));
827 }
828 return 0;
829}
830
831
832/**
833 * nes_netdev_set_multicast_list
834 */
Roland Dreier1a855fbf2008-04-16 21:01:09 -0700835static void nes_netdev_set_multicast_list(struct net_device *netdev)
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800836{
837 struct nes_vnic *nesvnic = netdev_priv(netdev);
838 struct nes_device *nesdev = nesvnic->nesdev;
839 struct dev_mc_list *multicast_addr;
840 u32 nic_active_bit;
841 u32 nic_active;
842 u32 perfect_filter_register_address;
843 u32 macaddr_low;
844 u16 macaddr_high;
845 u8 mc_all_on = 0;
846 u8 mc_index;
847 int mc_nic_index = -1;
848
849 nic_active_bit = 1 << nesvnic->nic_index;
850
851 if (netdev->flags & IFF_PROMISC) {
852 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL);
853 nic_active |= nic_active_bit;
854 nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active);
855 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL);
856 nic_active |= nic_active_bit;
857 nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
858 mc_all_on = 1;
859 } else if ((netdev->flags & IFF_ALLMULTI) || (netdev->mc_count > NES_MULTICAST_PF_MAX) ||
860 (nesvnic->nic_index > 3)) {
861 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL);
862 nic_active |= nic_active_bit;
863 nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active);
864 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL);
865 nic_active &= ~nic_active_bit;
866 nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
867 mc_all_on = 1;
868 } else {
869 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL);
870 nic_active &= ~nic_active_bit;
871 nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active);
872 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL);
873 nic_active &= ~nic_active_bit;
874 nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
875 }
876
877 nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscous = %d, All Multicast = %d.\n",
878 netdev->mc_count, (netdev->flags & IFF_PROMISC)?1:0,
879 (netdev->flags & IFF_ALLMULTI)?1:0);
880 if (!mc_all_on) {
881 multicast_addr = netdev->mc_list;
882 perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW + 0x80;
883 perfect_filter_register_address += nesvnic->nic_index*0x40;
884 for (mc_index=0; mc_index < NES_MULTICAST_PF_MAX; mc_index++) {
885 while (multicast_addr && nesvnic->mcrq_mcast_filter && ((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic, multicast_addr->dmi_addr)) == 0))
886 multicast_addr = multicast_addr->next;
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800887 if (mc_nic_index < 0)
888 mc_nic_index = nesvnic->nic_index;
889 if (multicast_addr) {
890 nes_debug(NES_DBG_NIC_RX, "Assigning MC Address = %02X%02X%02X%02X%02X%02X to register 0x%04X nic_idx=%d\n",
891 multicast_addr->dmi_addr[0], multicast_addr->dmi_addr[1],
892 multicast_addr->dmi_addr[2], multicast_addr->dmi_addr[3],
893 multicast_addr->dmi_addr[4], multicast_addr->dmi_addr[5],
894 perfect_filter_register_address+(mc_index * 8), mc_nic_index);
895 macaddr_high = ((u16)multicast_addr->dmi_addr[0]) << 8;
896 macaddr_high += (u16)multicast_addr->dmi_addr[1];
897 macaddr_low = ((u32)multicast_addr->dmi_addr[2]) << 24;
898 macaddr_low += ((u32)multicast_addr->dmi_addr[3]) << 16;
899 macaddr_low += ((u32)multicast_addr->dmi_addr[4]) << 8;
900 macaddr_low += (u32)multicast_addr->dmi_addr[5];
901 nes_write_indexed(nesdev,
902 perfect_filter_register_address+(mc_index * 8),
903 macaddr_low);
904 nes_write_indexed(nesdev,
905 perfect_filter_register_address+4+(mc_index * 8),
906 (u32)macaddr_high | NES_MAC_ADDR_VALID |
907 ((((u32)(1<<mc_nic_index)) << 16)));
908 multicast_addr = multicast_addr->next;
909 } else {
910 nes_debug(NES_DBG_NIC_RX, "Clearing MC Address at register 0x%04X\n",
911 perfect_filter_register_address+(mc_index * 8));
912 nes_write_indexed(nesdev,
913 perfect_filter_register_address+4+(mc_index * 8),
914 0);
915 }
916 }
917 }
918}
919
920
921/**
922 * nes_netdev_change_mtu
923 */
924static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu)
925{
926 struct nes_vnic *nesvnic = netdev_priv(netdev);
927 struct nes_device *nesdev = nesvnic->nesdev;
928 int ret = 0;
929 u8 jumbomode=0;
930
931 if ((new_mtu < ETH_ZLEN) || (new_mtu > max_mtu))
932 return -EINVAL;
933
934 netdev->mtu = new_mtu;
Chien Tungedd2fd62008-02-15 21:00:36 -0600935 nesvnic->max_frame_size = new_mtu + VLAN_ETH_HLEN;
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800936
937 if (netdev->mtu > 1500) {
938 jumbomode=1;
939 }
940 nes_nic_init_timer_defaults(nesdev, jumbomode);
941
942 if (netif_running(netdev)) {
943 nes_netdev_stop(netdev);
944 nes_netdev_open(netdev);
945 }
946
947 return ret;
948}
949
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800950#define NES_ETHTOOL_STAT_COUNT 55
951static const char nes_ethtool_stringset[NES_ETHTOOL_STAT_COUNT][ETH_GSTRING_LEN] = {
952 "Link Change Interrupts",
953 "Linearized SKBs",
954 "T/GSO Requests",
955 "Pause Frames Sent",
956 "Pause Frames Received",
957 "Internal Routing Errors",
958 "SQ SW Dropped SKBs",
959 "SQ Locked",
960 "SQ Full",
961 "Segmented TSO Requests",
962 "Rx Symbol Errors",
963 "Rx Jabber Errors",
964 "Rx Oversized Frames",
965 "Rx Short Frames",
966 "Endnode Rx Discards",
967 "Endnode Rx Octets",
968 "Endnode Rx Frames",
969 "Endnode Tx Octets",
970 "Endnode Tx Frames",
971 "mh detected",
972 "mh pauses",
973 "Retransmission Count",
974 "CM Connects",
975 "CM Accepts",
976 "Disconnects",
977 "Connected Events",
978 "Connect Requests",
979 "CM Rejects",
980 "ModifyQP Timeouts",
981 "CreateQPs",
982 "SW DestroyQPs",
983 "DestroyQPs",
984 "CM Closes",
985 "CM Packets Sent",
986 "CM Packets Bounced",
987 "CM Packets Created",
988 "CM Packets Rcvd",
989 "CM Packets Dropped",
990 "CM Packets Retrans",
991 "CM Listens Created",
992 "CM Listens Destroyed",
993 "CM Backlog Drops",
994 "CM Loopbacks",
995 "CM Nodes Created",
996 "CM Nodes Destroyed",
997 "CM Accel Drops",
998 "CM Resets Received",
999 "Timer Inits",
1000 "CQ Depth 1",
1001 "CQ Depth 4",
1002 "CQ Depth 16",
1003 "CQ Depth 24",
1004 "CQ Depth 32",
1005 "CQ Depth 128",
1006 "CQ Depth 256",
1007};
1008
1009
1010/**
1011 * nes_netdev_get_rx_csum
1012 */
1013static u32 nes_netdev_get_rx_csum (struct net_device *netdev)
1014{
1015 struct nes_vnic *nesvnic = netdev_priv(netdev);
1016
1017 if (nesvnic->rx_checksum_disabled)
1018 return 0;
1019 else
1020 return 1;
1021}
1022
1023
1024/**
1025 * nes_netdev_set_rc_csum
1026 */
1027static int nes_netdev_set_rx_csum(struct net_device *netdev, u32 enable)
1028{
1029 struct nes_vnic *nesvnic = netdev_priv(netdev);
1030
1031 if (enable)
1032 nesvnic->rx_checksum_disabled = 0;
1033 else
1034 nesvnic->rx_checksum_disabled = 1;
1035 return 0;
1036}
1037
1038
1039/**
1040 * nes_netdev_get_stats_count
1041 */
1042static int nes_netdev_get_stats_count(struct net_device *netdev)
1043{
1044 return NES_ETHTOOL_STAT_COUNT;
1045}
1046
1047
1048/**
1049 * nes_netdev_get_strings
1050 */
1051static void nes_netdev_get_strings(struct net_device *netdev, u32 stringset,
1052 u8 *ethtool_strings)
1053{
1054 if (stringset == ETH_SS_STATS)
1055 memcpy(ethtool_strings,
1056 &nes_ethtool_stringset,
1057 sizeof(nes_ethtool_stringset));
1058}
1059
1060
1061/**
1062 * nes_netdev_get_ethtool_stats
1063 */
1064static void nes_netdev_get_ethtool_stats(struct net_device *netdev,
1065 struct ethtool_stats *target_ethtool_stats, u64 *target_stat_values)
1066{
1067 u64 u64temp;
1068 struct nes_vnic *nesvnic = netdev_priv(netdev);
1069 struct nes_device *nesdev = nesvnic->nesdev;
1070 u32 nic_count;
1071 u32 u32temp;
1072
1073 target_ethtool_stats->n_stats = NES_ETHTOOL_STAT_COUNT;
1074 target_stat_values[0] = nesvnic->nesdev->link_status_interrupts;
1075 target_stat_values[1] = nesvnic->linearized_skbs;
1076 target_stat_values[2] = nesvnic->tso_requests;
1077
1078 u32temp = nes_read_indexed(nesdev,
1079 NES_IDX_MAC_TX_PAUSE_FRAMES + (nesvnic->nesdev->mac_index*0x200));
1080 nesvnic->nesdev->mac_pause_frames_sent += u32temp;
1081 target_stat_values[3] = nesvnic->nesdev->mac_pause_frames_sent;
1082
1083 u32temp = nes_read_indexed(nesdev,
1084 NES_IDX_MAC_RX_PAUSE_FRAMES + (nesvnic->nesdev->mac_index*0x200));
1085 nesvnic->nesdev->mac_pause_frames_received += u32temp;
1086
1087 u32temp = nes_read_indexed(nesdev,
1088 NES_IDX_PORT_RX_DISCARDS + (nesvnic->nesdev->mac_index*0x40));
1089 nesvnic->nesdev->port_rx_discards += u32temp;
1090 nesvnic->netstats.rx_dropped += u32temp;
1091
1092 u32temp = nes_read_indexed(nesdev,
1093 NES_IDX_PORT_TX_DISCARDS + (nesvnic->nesdev->mac_index*0x40));
1094 nesvnic->nesdev->port_tx_discards += u32temp;
1095 nesvnic->netstats.tx_dropped += u32temp;
1096
1097 for (nic_count = 0; nic_count < NES_MAX_PORT_COUNT; nic_count++) {
1098 if (nesvnic->qp_nic_index[nic_count] == 0xf)
1099 break;
1100
1101 u32temp = nes_read_indexed(nesdev,
1102 NES_IDX_ENDNODE0_NSTAT_RX_DISCARD +
1103 (nesvnic->qp_nic_index[nic_count]*0x200));
1104 nesvnic->netstats.rx_dropped += u32temp;
1105 nesvnic->endnode_nstat_rx_discard += u32temp;
1106
1107 u64temp = (u64)nes_read_indexed(nesdev,
1108 NES_IDX_ENDNODE0_NSTAT_RX_OCTETS_LO +
1109 (nesvnic->qp_nic_index[nic_count]*0x200));
1110 u64temp += ((u64)nes_read_indexed(nesdev,
1111 NES_IDX_ENDNODE0_NSTAT_RX_OCTETS_HI +
1112 (nesvnic->qp_nic_index[nic_count]*0x200))) << 32;
1113
1114 nesvnic->endnode_nstat_rx_octets += u64temp;
1115 nesvnic->netstats.rx_bytes += u64temp;
1116
1117 u64temp = (u64)nes_read_indexed(nesdev,
1118 NES_IDX_ENDNODE0_NSTAT_RX_FRAMES_LO +
1119 (nesvnic->qp_nic_index[nic_count]*0x200));
1120 u64temp += ((u64)nes_read_indexed(nesdev,
1121 NES_IDX_ENDNODE0_NSTAT_RX_FRAMES_HI +
1122 (nesvnic->qp_nic_index[nic_count]*0x200))) << 32;
1123
1124 nesvnic->endnode_nstat_rx_frames += u64temp;
1125 nesvnic->netstats.rx_packets += u64temp;
1126
1127 u64temp = (u64)nes_read_indexed(nesdev,
1128 NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_LO +
1129 (nesvnic->qp_nic_index[nic_count]*0x200));
1130 u64temp += ((u64)nes_read_indexed(nesdev,
1131 NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_HI +
1132 (nesvnic->qp_nic_index[nic_count]*0x200))) << 32;
1133
1134 nesvnic->endnode_nstat_tx_octets += u64temp;
1135 nesvnic->netstats.tx_bytes += u64temp;
1136
1137 u64temp = (u64)nes_read_indexed(nesdev,
1138 NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_LO +
1139 (nesvnic->qp_nic_index[nic_count]*0x200));
1140 u64temp += ((u64)nes_read_indexed(nesdev,
1141 NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_HI +
1142 (nesvnic->qp_nic_index[nic_count]*0x200))) << 32;
1143
1144 nesvnic->endnode_nstat_tx_frames += u64temp;
1145 nesvnic->netstats.tx_packets += u64temp;
1146
1147 u32temp = nes_read_indexed(nesdev,
1148 NES_IDX_IPV4_TCP_REXMITS + (nesvnic->qp_nic_index[nic_count]*0x200));
1149 nesvnic->endnode_ipv4_tcp_retransmits += u32temp;
1150 }
1151
1152 target_stat_values[4] = nesvnic->nesdev->mac_pause_frames_received;
1153 target_stat_values[5] = nesdev->nesadapter->nic_rx_eth_route_err;
1154 target_stat_values[6] = nesvnic->tx_sw_dropped;
1155 target_stat_values[7] = nesvnic->sq_locked;
1156 target_stat_values[8] = nesvnic->sq_full;
1157 target_stat_values[9] = nesvnic->segmented_tso_requests;
1158 target_stat_values[10] = nesvnic->nesdev->mac_rx_symbol_err_frames;
1159 target_stat_values[11] = nesvnic->nesdev->mac_rx_jabber_frames;
1160 target_stat_values[12] = nesvnic->nesdev->mac_rx_oversized_frames;
1161 target_stat_values[13] = nesvnic->nesdev->mac_rx_short_frames;
1162 target_stat_values[14] = nesvnic->endnode_nstat_rx_discard;
1163 target_stat_values[15] = nesvnic->endnode_nstat_rx_octets;
1164 target_stat_values[16] = nesvnic->endnode_nstat_rx_frames;
1165 target_stat_values[17] = nesvnic->endnode_nstat_tx_octets;
1166 target_stat_values[18] = nesvnic->endnode_nstat_tx_frames;
1167 target_stat_values[19] = mh_detected;
1168 target_stat_values[20] = mh_pauses_sent;
1169 target_stat_values[21] = nesvnic->endnode_ipv4_tcp_retransmits;
1170 target_stat_values[22] = atomic_read(&cm_connects);
1171 target_stat_values[23] = atomic_read(&cm_accepts);
1172 target_stat_values[24] = atomic_read(&cm_disconnects);
1173 target_stat_values[25] = atomic_read(&cm_connecteds);
1174 target_stat_values[26] = atomic_read(&cm_connect_reqs);
1175 target_stat_values[27] = atomic_read(&cm_rejects);
1176 target_stat_values[28] = atomic_read(&mod_qp_timouts);
1177 target_stat_values[29] = atomic_read(&qps_created);
1178 target_stat_values[30] = atomic_read(&sw_qps_destroyed);
1179 target_stat_values[31] = atomic_read(&qps_destroyed);
1180 target_stat_values[32] = atomic_read(&cm_closes);
1181 target_stat_values[33] = cm_packets_sent;
1182 target_stat_values[34] = cm_packets_bounced;
1183 target_stat_values[35] = cm_packets_created;
1184 target_stat_values[36] = cm_packets_received;
1185 target_stat_values[37] = cm_packets_dropped;
1186 target_stat_values[38] = cm_packets_retrans;
1187 target_stat_values[39] = cm_listens_created;
1188 target_stat_values[40] = cm_listens_destroyed;
1189 target_stat_values[41] = cm_backlog_drops;
1190 target_stat_values[42] = atomic_read(&cm_loopbacks);
1191 target_stat_values[43] = atomic_read(&cm_nodes_created);
1192 target_stat_values[44] = atomic_read(&cm_nodes_destroyed);
1193 target_stat_values[45] = atomic_read(&cm_accel_dropped_pkts);
1194 target_stat_values[46] = atomic_read(&cm_resets_recvd);
1195 target_stat_values[47] = int_mod_timer_init;
1196 target_stat_values[48] = int_mod_cq_depth_1;
1197 target_stat_values[49] = int_mod_cq_depth_4;
1198 target_stat_values[50] = int_mod_cq_depth_16;
1199 target_stat_values[51] = int_mod_cq_depth_24;
1200 target_stat_values[52] = int_mod_cq_depth_32;
1201 target_stat_values[53] = int_mod_cq_depth_128;
1202 target_stat_values[54] = int_mod_cq_depth_256;
1203
1204}
1205
1206
1207/**
1208 * nes_netdev_get_drvinfo
1209 */
1210static void nes_netdev_get_drvinfo(struct net_device *netdev,
1211 struct ethtool_drvinfo *drvinfo)
1212{
1213 struct nes_vnic *nesvnic = netdev_priv(netdev);
1214
1215 strcpy(drvinfo->driver, DRV_NAME);
1216 strcpy(drvinfo->bus_info, pci_name(nesvnic->nesdev->pcidev));
1217 strcpy(drvinfo->fw_version, "TBD");
1218 strcpy(drvinfo->version, DRV_VERSION);
1219 drvinfo->n_stats = nes_netdev_get_stats_count(netdev);
1220 drvinfo->testinfo_len = 0;
1221 drvinfo->eedump_len = 0;
1222 drvinfo->regdump_len = 0;
1223}
1224
1225
1226/**
1227 * nes_netdev_set_coalesce
1228 */
1229static int nes_netdev_set_coalesce(struct net_device *netdev,
1230 struct ethtool_coalesce *et_coalesce)
1231{
1232 struct nes_vnic *nesvnic = netdev_priv(netdev);
1233 struct nes_device *nesdev = nesvnic->nesdev;
1234 struct nes_adapter *nesadapter = nesdev->nesadapter;
1235 struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer;
1236 unsigned long flags;
1237
1238 spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags);
1239 if (et_coalesce->rx_max_coalesced_frames_low) {
1240 shared_timer->threshold_low = et_coalesce->rx_max_coalesced_frames_low;
1241 }
1242 if (et_coalesce->rx_max_coalesced_frames_irq) {
1243 shared_timer->threshold_target = et_coalesce->rx_max_coalesced_frames_irq;
1244 }
1245 if (et_coalesce->rx_max_coalesced_frames_high) {
1246 shared_timer->threshold_high = et_coalesce->rx_max_coalesced_frames_high;
1247 }
1248 if (et_coalesce->rx_coalesce_usecs_low) {
1249 shared_timer->timer_in_use_min = et_coalesce->rx_coalesce_usecs_low;
1250 }
1251 if (et_coalesce->rx_coalesce_usecs_high) {
1252 shared_timer->timer_in_use_max = et_coalesce->rx_coalesce_usecs_high;
1253 }
1254 spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags);
1255
1256 /* using this to drive total interrupt moderation */
1257 nesadapter->et_rx_coalesce_usecs_irq = et_coalesce->rx_coalesce_usecs_irq;
1258 if (et_coalesce->use_adaptive_rx_coalesce) {
1259 nesadapter->et_use_adaptive_rx_coalesce = 1;
1260 nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT_DYNAMIC;
1261 nesadapter->et_rx_coalesce_usecs_irq = 0;
1262 if (et_coalesce->pkt_rate_low) {
1263 nesadapter->et_pkt_rate_low = et_coalesce->pkt_rate_low;
1264 }
1265 } else {
1266 nesadapter->et_use_adaptive_rx_coalesce = 0;
1267 nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT;
1268 if (nesadapter->et_rx_coalesce_usecs_irq) {
1269 nes_write32(nesdev->regs+NES_PERIODIC_CONTROL,
1270 0x80000000 | ((u32)(nesadapter->et_rx_coalesce_usecs_irq*8)));
1271 }
1272 }
1273 return 0;
1274}
1275
1276
1277/**
1278 * nes_netdev_get_coalesce
1279 */
1280static int nes_netdev_get_coalesce(struct net_device *netdev,
1281 struct ethtool_coalesce *et_coalesce)
1282{
1283 struct nes_vnic *nesvnic = netdev_priv(netdev);
1284 struct nes_device *nesdev = nesvnic->nesdev;
1285 struct nes_adapter *nesadapter = nesdev->nesadapter;
1286 struct ethtool_coalesce temp_et_coalesce;
1287 struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer;
1288 unsigned long flags;
1289
1290 memset(&temp_et_coalesce, 0, sizeof(temp_et_coalesce));
1291 temp_et_coalesce.rx_coalesce_usecs_irq = nesadapter->et_rx_coalesce_usecs_irq;
1292 temp_et_coalesce.use_adaptive_rx_coalesce = nesadapter->et_use_adaptive_rx_coalesce;
1293 temp_et_coalesce.rate_sample_interval = nesadapter->et_rate_sample_interval;
1294 temp_et_coalesce.pkt_rate_low = nesadapter->et_pkt_rate_low;
1295 spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags);
1296 temp_et_coalesce.rx_max_coalesced_frames_low = shared_timer->threshold_low;
1297 temp_et_coalesce.rx_max_coalesced_frames_irq = shared_timer->threshold_target;
1298 temp_et_coalesce.rx_max_coalesced_frames_high = shared_timer->threshold_high;
1299 temp_et_coalesce.rx_coalesce_usecs_low = shared_timer->timer_in_use_min;
1300 temp_et_coalesce.rx_coalesce_usecs_high = shared_timer->timer_in_use_max;
1301 if (nesadapter->et_use_adaptive_rx_coalesce) {
1302 temp_et_coalesce.rx_coalesce_usecs_irq = shared_timer->timer_in_use;
1303 }
1304 spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags);
1305 memcpy(et_coalesce, &temp_et_coalesce, sizeof(*et_coalesce));
1306 return 0;
1307}
1308
1309
1310/**
1311 * nes_netdev_get_pauseparam
1312 */
1313static void nes_netdev_get_pauseparam(struct net_device *netdev,
1314 struct ethtool_pauseparam *et_pauseparam)
1315{
1316 struct nes_vnic *nesvnic = netdev_priv(netdev);
1317
1318 et_pauseparam->autoneg = 0;
1319 et_pauseparam->rx_pause = (nesvnic->nesdev->disable_rx_flow_control == 0) ? 1:0;
1320 et_pauseparam->tx_pause = (nesvnic->nesdev->disable_tx_flow_control == 0) ? 1:0;
1321}
1322
1323
1324/**
1325 * nes_netdev_set_pauseparam
1326 */
1327static int nes_netdev_set_pauseparam(struct net_device *netdev,
1328 struct ethtool_pauseparam *et_pauseparam)
1329{
1330 struct nes_vnic *nesvnic = netdev_priv(netdev);
1331 struct nes_device *nesdev = nesvnic->nesdev;
1332 u32 u32temp;
1333
1334 if (et_pauseparam->autoneg) {
1335 /* TODO: should return unsupported */
1336 return 0;
1337 }
1338 if ((et_pauseparam->tx_pause == 1) && (nesdev->disable_tx_flow_control == 1)) {
1339 u32temp = nes_read_indexed(nesdev,
1340 NES_IDX_MAC_TX_CONFIG + (nesdev->mac_index*0x200));
1341 u32temp |= NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE;
1342 nes_write_indexed(nesdev,
1343 NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE + (nesdev->mac_index*0x200), u32temp);
1344 nesdev->disable_tx_flow_control = 0;
1345 } else if ((et_pauseparam->tx_pause == 0) && (nesdev->disable_tx_flow_control == 0)) {
1346 u32temp = nes_read_indexed(nesdev,
1347 NES_IDX_MAC_TX_CONFIG + (nesdev->mac_index*0x200));
1348 u32temp &= ~NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE;
1349 nes_write_indexed(nesdev,
1350 NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE + (nesdev->mac_index*0x200), u32temp);
1351 nesdev->disable_tx_flow_control = 1;
1352 }
1353 if ((et_pauseparam->rx_pause == 1) && (nesdev->disable_rx_flow_control == 1)) {
1354 u32temp = nes_read_indexed(nesdev,
1355 NES_IDX_MPP_DEBUG + (nesdev->mac_index*0x40));
1356 u32temp &= ~NES_IDX_MPP_DEBUG_PORT_DISABLE_PAUSE;
1357 nes_write_indexed(nesdev,
1358 NES_IDX_MPP_DEBUG + (nesdev->mac_index*0x40), u32temp);
1359 nesdev->disable_rx_flow_control = 0;
1360 } else if ((et_pauseparam->rx_pause == 0) && (nesdev->disable_rx_flow_control == 0)) {
1361 u32temp = nes_read_indexed(nesdev,
1362 NES_IDX_MPP_DEBUG + (nesdev->mac_index*0x40));
1363 u32temp |= NES_IDX_MPP_DEBUG_PORT_DISABLE_PAUSE;
1364 nes_write_indexed(nesdev,
1365 NES_IDX_MPP_DEBUG + (nesdev->mac_index*0x40), u32temp);
1366 nesdev->disable_rx_flow_control = 1;
1367 }
1368
1369 return 0;
1370}
1371
1372
1373/**
1374 * nes_netdev_get_settings
1375 */
1376static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd *et_cmd)
1377{
1378 struct nes_vnic *nesvnic = netdev_priv(netdev);
1379 struct nes_device *nesdev = nesvnic->nesdev;
1380 struct nes_adapter *nesadapter = nesdev->nesadapter;
1381 u16 phy_data;
1382
1383 et_cmd->duplex = DUPLEX_FULL;
1384 et_cmd->port = PORT_MII;
1385 if (nesadapter->OneG_Mode) {
1386 et_cmd->supported = SUPPORTED_1000baseT_Full|SUPPORTED_Autoneg;
1387 et_cmd->advertising = ADVERTISED_1000baseT_Full|ADVERTISED_Autoneg;
1388 et_cmd->speed = SPEED_1000;
1389 nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index],
1390 &phy_data);
1391 if (phy_data&0x1000) {
1392 et_cmd->autoneg = AUTONEG_ENABLE;
1393 } else {
1394 et_cmd->autoneg = AUTONEG_DISABLE;
1395 }
1396 et_cmd->transceiver = XCVR_EXTERNAL;
1397 et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index];
1398 } else {
1399 if (nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) {
1400 et_cmd->transceiver = XCVR_EXTERNAL;
1401 et_cmd->port = PORT_FIBRE;
1402 et_cmd->supported = SUPPORTED_FIBRE;
1403 et_cmd->advertising = ADVERTISED_FIBRE;
1404 et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index];
1405 } else {
1406 et_cmd->transceiver = XCVR_INTERNAL;
1407 et_cmd->supported = SUPPORTED_10000baseT_Full;
1408 et_cmd->advertising = ADVERTISED_10000baseT_Full;
1409 et_cmd->phy_address = nesdev->mac_index;
1410 }
1411 et_cmd->speed = SPEED_10000;
1412 et_cmd->autoneg = AUTONEG_DISABLE;
1413 }
1414 et_cmd->maxtxpkt = 511;
1415 et_cmd->maxrxpkt = 511;
1416 return 0;
1417}
1418
1419
1420/**
1421 * nes_netdev_set_settings
1422 */
1423static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd *et_cmd)
1424{
1425 struct nes_vnic *nesvnic = netdev_priv(netdev);
1426 struct nes_device *nesdev = nesvnic->nesdev;
1427 struct nes_adapter *nesadapter = nesdev->nesadapter;
1428 u16 phy_data;
1429
1430 if (nesadapter->OneG_Mode) {
1431 nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index],
1432 &phy_data);
1433 if (et_cmd->autoneg) {
1434 /* Turn on Full duplex, Autoneg, and restart autonegotiation */
1435 phy_data |= 0x1300;
1436 } else {
1437 // Turn off autoneg
1438 phy_data &= ~0x1000;
1439 }
1440 nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index],
1441 phy_data);
1442 }
1443
1444 return 0;
1445}
1446
1447
1448static struct ethtool_ops nes_ethtool_ops = {
1449 .get_link = ethtool_op_get_link,
1450 .get_settings = nes_netdev_get_settings,
1451 .set_settings = nes_netdev_set_settings,
1452 .get_tx_csum = ethtool_op_get_tx_csum,
1453 .get_rx_csum = nes_netdev_get_rx_csum,
1454 .get_sg = ethtool_op_get_sg,
1455 .get_strings = nes_netdev_get_strings,
1456 .get_stats_count = nes_netdev_get_stats_count,
1457 .get_ethtool_stats = nes_netdev_get_ethtool_stats,
1458 .get_drvinfo = nes_netdev_get_drvinfo,
1459 .get_coalesce = nes_netdev_get_coalesce,
1460 .set_coalesce = nes_netdev_set_coalesce,
1461 .get_pauseparam = nes_netdev_get_pauseparam,
1462 .set_pauseparam = nes_netdev_set_pauseparam,
1463 .set_tx_csum = ethtool_op_set_tx_csum,
1464 .set_rx_csum = nes_netdev_set_rx_csum,
1465 .set_sg = ethtool_op_set_sg,
1466 .get_tso = ethtool_op_get_tso,
1467 .set_tso = ethtool_op_set_tso,
1468};
1469
1470
1471static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
1472{
1473 struct nes_vnic *nesvnic = netdev_priv(netdev);
1474 struct nes_device *nesdev = nesvnic->nesdev;
Chien Tungedd2fd62008-02-15 21:00:36 -06001475 struct nes_adapter *nesadapter = nesdev->nesadapter;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001476 u32 u32temp;
Chien Tungedd2fd62008-02-15 21:00:36 -06001477 unsigned long flags;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001478
Chien Tungedd2fd62008-02-15 21:00:36 -06001479 spin_lock_irqsave(&nesadapter->phy_lock, flags);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001480 nesvnic->vlan_grp = grp;
1481
Chien Tungedd2fd62008-02-15 21:00:36 -06001482 nes_debug(NES_DBG_NETDEV, "%s: %s\n", __func__, netdev->name);
1483
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001484 /* Enable/Disable VLAN Stripping */
1485 u32temp = nes_read_indexed(nesdev, NES_IDX_PCIX_DIAG);
1486 if (grp)
1487 u32temp &= 0xfdffffff;
1488 else
1489 u32temp |= 0x02000000;
1490
1491 nes_write_indexed(nesdev, NES_IDX_PCIX_DIAG, u32temp);
Chien Tungedd2fd62008-02-15 21:00:36 -06001492 spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001493}
1494
1495
1496/**
1497 * nes_netdev_init - initialize network device
1498 */
1499struct net_device *nes_netdev_init(struct nes_device *nesdev,
1500 void __iomem *mmio_addr)
1501{
1502 u64 u64temp;
1503 struct nes_vnic *nesvnic = NULL;
1504 struct net_device *netdev;
1505 struct nic_qp_map *curr_qp_map;
1506 u32 u32temp;
1507 u16 phy_data;
1508 u16 temp_phy_data;
1509
1510 netdev = alloc_etherdev(sizeof(struct nes_vnic));
1511 if (!netdev) {
1512 printk(KERN_ERR PFX "nesvnic etherdev alloc failed");
1513 return NULL;
1514 }
1515
1516 nes_debug(NES_DBG_INIT, "netdev = %p, %s\n", netdev, netdev->name);
1517
1518 SET_NETDEV_DEV(netdev, &nesdev->pcidev->dev);
1519
1520 nesvnic = netdev_priv(netdev);
1521 memset(nesvnic, 0, sizeof(*nesvnic));
1522
1523 netdev->open = nes_netdev_open;
1524 netdev->stop = nes_netdev_stop;
1525 netdev->hard_start_xmit = nes_netdev_start_xmit;
1526 netdev->get_stats = nes_netdev_get_stats;
1527 netdev->tx_timeout = nes_netdev_tx_timeout;
1528 netdev->set_mac_address = nes_netdev_set_mac_address;
1529 netdev->set_multicast_list = nes_netdev_set_multicast_list;
1530 netdev->change_mtu = nes_netdev_change_mtu;
1531 netdev->watchdog_timeo = NES_TX_TIMEOUT;
1532 netdev->irq = nesdev->pcidev->irq;
1533 netdev->mtu = ETH_DATA_LEN;
1534 netdev->hard_header_len = ETH_HLEN;
1535 netdev->addr_len = ETH_ALEN;
1536 netdev->type = ARPHRD_ETHER;
1537 netdev->features = NETIF_F_HIGHDMA;
1538 netdev->ethtool_ops = &nes_ethtool_ops;
1539 netif_napi_add(netdev, &nesvnic->napi, nes_netdev_poll, 128);
1540 nes_debug(NES_DBG_INIT, "Enabling VLAN Insert/Delete.\n");
1541 netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
1542 netdev->vlan_rx_register = nes_netdev_vlan_rx_register;
1543 netdev->features |= NETIF_F_LLTX;
1544
1545 /* Fill in the port structure */
1546 nesvnic->netdev = netdev;
1547 nesvnic->nesdev = nesdev;
1548 nesvnic->msg_enable = netif_msg_init(debug, default_msg);
1549 nesvnic->netdev_index = nesdev->netdev_count;
1550 nesvnic->perfect_filter_index = nesdev->nesadapter->netdev_count;
Chien Tungedd2fd62008-02-15 21:00:36 -06001551 nesvnic->max_frame_size = netdev->mtu + netdev->hard_header_len + VLAN_HLEN;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001552
1553 curr_qp_map = nic_qp_mapping_per_function[PCI_FUNC(nesdev->pcidev->devfn)];
1554 nesvnic->nic.qp_id = curr_qp_map[nesdev->netdev_count].qpid;
1555 nesvnic->nic_index = curr_qp_map[nesdev->netdev_count].nic_index;
1556 nesvnic->logical_port = curr_qp_map[nesdev->netdev_count].logical_port;
1557
1558 /* Setup the burned in MAC address */
1559 u64temp = (u64)nesdev->nesadapter->mac_addr_low;
1560 u64temp += ((u64)nesdev->nesadapter->mac_addr_high) << 32;
1561 u64temp += nesvnic->nic_index;
1562 netdev->dev_addr[0] = (u8)(u64temp>>40);
1563 netdev->dev_addr[1] = (u8)(u64temp>>32);
1564 netdev->dev_addr[2] = (u8)(u64temp>>24);
1565 netdev->dev_addr[3] = (u8)(u64temp>>16);
1566 netdev->dev_addr[4] = (u8)(u64temp>>8);
1567 netdev->dev_addr[5] = (u8)u64temp;
1568 memcpy(netdev->perm_addr, netdev->dev_addr, 6);
1569
1570 if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV)) {
1571 netdev->features |= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
1572 netdev->features |= NETIF_F_GSO | NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
1573 } else {
1574 netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
1575 }
1576
1577 nes_debug(NES_DBG_INIT, "nesvnic = %p, reported features = 0x%lX, QPid = %d,"
1578 " nic_index = %d, logical_port = %d, mac_index = %d.\n",
1579 nesvnic, (unsigned long)netdev->features, nesvnic->nic.qp_id,
1580 nesvnic->nic_index, nesvnic->logical_port, nesdev->mac_index);
1581
1582 if (nesvnic->nesdev->nesadapter->port_count == 1) {
1583 nesvnic->qp_nic_index[0] = nesvnic->nic_index;
1584 nesvnic->qp_nic_index[1] = nesvnic->nic_index + 1;
1585 if (nes_drv_opt & NES_DRV_OPT_DUAL_LOGICAL_PORT) {
1586 nesvnic->qp_nic_index[2] = 0xf;
1587 nesvnic->qp_nic_index[3] = 0xf;
1588 } else {
1589 nesvnic->qp_nic_index[2] = nesvnic->nic_index + 2;
1590 nesvnic->qp_nic_index[3] = nesvnic->nic_index + 3;
1591 }
1592 } else {
1593 if (nesvnic->nesdev->nesadapter->port_count == 2) {
1594 nesvnic->qp_nic_index[0] = nesvnic->nic_index;
1595 nesvnic->qp_nic_index[1] = nesvnic->nic_index + 2;
1596 nesvnic->qp_nic_index[2] = 0xf;
1597 nesvnic->qp_nic_index[3] = 0xf;
1598 } else {
1599 nesvnic->qp_nic_index[0] = nesvnic->nic_index;
1600 nesvnic->qp_nic_index[1] = 0xf;
1601 nesvnic->qp_nic_index[2] = 0xf;
1602 nesvnic->qp_nic_index[3] = 0xf;
1603 }
1604 }
1605 nesvnic->next_qp_nic_index = 0;
1606
1607 if (nesdev->netdev_count == 0) {
1608 nesvnic->rdma_enabled = 1;
1609 } else {
1610 nesvnic->rdma_enabled = 0;
1611 }
1612 nesvnic->nic_cq.cq_number = nesvnic->nic.qp_id;
1613 spin_lock_init(&nesvnic->tx_lock);
1614 nesdev->netdev[nesdev->netdev_count] = netdev;
1615
1616 nes_debug(NES_DBG_INIT, "Adding nesvnic (%p) to the adapters nesvnic_list for MAC%d.\n",
1617 nesvnic, nesdev->mac_index);
1618 list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]);
1619
1620 if ((nesdev->netdev_count == 0) &&
Glenn Streiff11e07042008-02-15 11:41:27 -06001621 (PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001622 nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n",
1623 NES_IDX_PHY_PCS_CONTROL_STATUS0+(0x200*(nesvnic->logical_port&1)));
1624 u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
1625 (0x200*(nesvnic->logical_port&1)));
1626 u32temp |= 0x00200000;
1627 nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
1628 (0x200*(nesvnic->logical_port&1)), u32temp);
1629 u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
1630 (0x200*(nesvnic->logical_port&1)) );
1631 if ((u32temp&0x0f1f0000) == 0x0f0f0000) {
1632 if (nesdev->nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) {
1633 nes_init_phy(nesdev);
1634 nes_read_10G_phy_reg(nesdev, 1,
1635 nesdev->nesadapter->phy_index[nesvnic->logical_port]);
1636 temp_phy_data = (u16)nes_read_indexed(nesdev,
1637 NES_IDX_MAC_MDIO_CONTROL);
1638 u32temp = 20;
1639 do {
1640 nes_read_10G_phy_reg(nesdev, 1,
1641 nesdev->nesadapter->phy_index[nesvnic->logical_port]);
1642 phy_data = (u16)nes_read_indexed(nesdev,
1643 NES_IDX_MAC_MDIO_CONTROL);
1644 if ((phy_data == temp_phy_data) || (!(--u32temp)))
1645 break;
1646 temp_phy_data = phy_data;
1647 } while (1);
1648 if (phy_data & 4) {
1649 nes_debug(NES_DBG_INIT, "The Link is UP!!.\n");
1650 nesvnic->linkup = 1;
1651 } else {
1652 nes_debug(NES_DBG_INIT, "The Link is DOWN!!.\n");
1653 }
1654 } else {
1655 nes_debug(NES_DBG_INIT, "The Link is UP!!.\n");
1656 nesvnic->linkup = 1;
1657 }
1658 }
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001659 /* clear the MAC interrupt status, assumes direct logical to physical mapping */
Glenn Streiff11e07042008-02-15 11:41:27 -06001660 u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index));
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001661 nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", u32temp);
Glenn Streiff11e07042008-02-15 11:41:27 -06001662 nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index), u32temp);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001663
Glenn Streiff11e07042008-02-15 11:41:27 -06001664 if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_IRIS)
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001665 nes_init_phy(nesdev);
1666
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001667 }
1668
1669 return netdev;
1670}
1671
1672
1673/**
1674 * nes_netdev_destroy - destroy network device structure
1675 */
1676void nes_netdev_destroy(struct net_device *netdev)
1677{
1678 struct nes_vnic *nesvnic = netdev_priv(netdev);
1679
1680 /* make sure 'stop' method is called by Linux stack */
1681 /* nes_netdev_stop(netdev); */
1682
1683 list_del(&nesvnic->list);
1684
1685 if (nesvnic->of_device_registered) {
1686 nes_destroy_ofa_device(nesvnic->nesibdev);
1687 }
1688
1689 free_netdev(netdev);
1690}
1691
1692
1693/**
1694 * nes_nic_cm_xmit -- CM calls this to send out pkts
1695 */
1696int nes_nic_cm_xmit(struct sk_buff *skb, struct net_device *netdev)
1697{
1698 int ret;
1699
1700 skb->dev = netdev;
1701 ret = dev_queue_xmit(skb);
1702 if (ret) {
1703 nes_debug(NES_DBG_CM, "Bad return code from dev_queue_xmit %d\n", ret);
1704 }
1705
1706 return ret;
1707}