-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbe2net-4.1.450.7.patch
13639 lines (13095 loc) · 378 KB
/
be2net-4.1.450.7.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
diff -r 099b2caaa48c drivers/net/benet/Makefile
--- a/drivers/net/benet/Makefile
+++ b/drivers/net/benet/Makefile
@@ -1,7 +1,9 @@
#
-# Makefile to build the network driver for ServerEngine's BladeEngine.
+# Makefile to build the be2net network driver
#
+EXTRA_CFLAGS += -DCONFIG_PALAU
+
obj-$(CONFIG_BE2NET) += be2net.o
-be2net-y := be_main.o be_cmds.o be_ethtool.o
+be2net-y := be_main.o be_cmds.o be_ethtool.o be_compat.o be_misc.o
diff -r 099b2caaa48c drivers/net/benet/be.h
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -1,24 +1,25 @@
/*
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2011 Emulex
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation. The full GNU General
+ * as published by the Free Software Foundation. The full GNU General
* Public License is included in this distribution in the file called COPYING.
*
* Contact Information:
*
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
*/
#ifndef BE_H
#define BE_H
#include <linux/pci.h>
+#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/version.h>
#include <linux/delay.h>
@@ -29,22 +30,45 @@
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/firmware.h>
+#include <linux/jhash.h>
+#include <linux/ethtool.h>
+#ifndef CONFIG_PALAU
+#include <linux/inet_lro.h>
+#endif
+#ifdef CONFIG_PALAU
+#include "be_compat.h"
+#endif
#include "be_hw.h"
-#define DRV_VER "2.102.147s"
+#ifdef CONFIG_PALAU
+#include "version.h"
+#define DRV_VER STR_BE_MAJOR "." STR_BE_MINOR "."\
+ STR_BE_BUILD "." STR_BE_BRANCH
+#else
+#define DRV_VER "2.0.348"
+#endif
#define DRV_NAME "be2net"
-#define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC"
-#define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC"
-#define OC_NAME "Emulex OneConnect 10Gbps NIC"
-#define OC_NAME1 "Emulex OneConnect 10Gbps NIC (be3)"
-#define DRV_DESC "ServerEngines BladeEngine 10Gbps NIC Driver"
+#define BE_NAME "Emulex BladeEngine2"
+#define BE3_NAME "Emulex BladeEngine3"
+#define OC_NAME "Emulex OneConnect"
+#define OC_NAME_BE OC_NAME "(be3)"
+#define OC_NAME_LANCER OC_NAME "(Lancer)"
+#define DRV_DESC "Emulex OneConnect 10Gbps NIC Driver"
-#define BE_VENDOR_ID 0x19a2
+#define BE_VENDOR_ID 0x19a2
+#define EMULEX_VENDOR_ID 0x10df
#define BE_DEVICE_ID1 0x211
#define BE_DEVICE_ID2 0x221
-#define OC_DEVICE_ID1 0x700
-#define OC_DEVICE_ID2 0x710
+#define OC_DEVICE_ID1 0x700 /* Device Id for BE2 cards */
+#define OC_DEVICE_ID2 0x710 /* Device Id for BE3 cards */
+#define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */
+#define OC_DEVICE_ID4 0xe228 /* Device id for VF in Lancer */
+
+#define OC_SUBSYS_DEVICE_ID1 0xE602
+#define OC_SUBSYS_DEVICE_ID2 0xE642
+#define OC_SUBSYS_DEVICE_ID3 0xE612
+#define OC_SUBSYS_DEVICE_ID4 0xE652
static inline char *nic_name(struct pci_dev *pdev)
{
@@ -52,7 +76,10 @@ static inline char *nic_name(struct pci_
case OC_DEVICE_ID1:
return OC_NAME;
case OC_DEVICE_ID2:
- return OC_NAME1;
+ return OC_NAME_BE;
+ case OC_DEVICE_ID3:
+ case OC_DEVICE_ID4:
+ return OC_NAME_LANCER;
case BE_DEVICE_ID2:
return BE3_NAME;
default:
@@ -61,7 +88,7 @@ static inline char *nic_name(struct pci_
}
/* Number of bytes of an RX frame that are copied to skb->data */
-#define BE_HDR_LEN 64
+#define BE_HDR_LEN ((u16) 64)
#define BE_MAX_JUMBO_FRAME_SIZE 9018
#define BE_MIN_MTU 256
@@ -77,10 +104,24 @@ static inline char *nic_name(struct pci_
#define MCC_Q_LEN 128 /* total size not to exceed 8 pages */
#define MCC_CQ_LEN 256
+#define MAX_RSS_QS 4 /* BE limit is 4 queues/port */
+
+#define MAX_RX_QS (MAX_RSS_QS + 1)
+
+#ifdef MQ_TX
+#define MAX_TX_QS 8
+#else
+#define MAX_TX_QS 1
+#endif
+
+#define BE_MAX_MSIX_VECTORS (MAX_RX_QS + 1)/* RSS qs + 1 def Rx + Tx */
#define BE_NAPI_WEIGHT 64
-#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */
+#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */
#define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST)
+#define BE_MAX_LRO_DESCRIPTORS 16
+#define BE_MAX_FRAGS_PER_FRAME (min((u32) 16, (u32) MAX_SKB_FRAGS))
+
#define FW_VER_LEN 32
struct be_dma_mem {
@@ -125,6 +166,11 @@ static inline void *queue_tail_node(stru
return q->dma_mem.va + q->tail * q->entry_size;
}
+static inline void *queue_index_node(struct be_queue_info *q, u16 index)
+{
+ return q->dma_mem.va + index * q->entry_size;
+}
+
static inline void queue_head_inc(struct be_queue_info *q)
{
index_inc(&q->head, q->len);
@@ -135,6 +181,7 @@ static inline void queue_tail_inc(struct
index_inc(&q->tail, q->len);
}
+
struct be_eq_obj {
struct be_queue_info q;
char desc[32];
@@ -144,6 +191,7 @@ struct be_eq_obj {
u16 min_eqd; /* in usecs */
u16 max_eqd; /* in usecs */
u16 cur_eqd; /* in usecs */
+ u8 eq_idx;
struct napi_struct napi;
};
@@ -154,44 +202,17 @@ struct be_mcc_obj {
bool rearm_cq;
};
-struct be_drvr_stats {
+struct be_tx_stats {
u32 be_tx_reqs; /* number of TX requests initiated */
u32 be_tx_stops; /* number of times TX Q was stopped */
- u32 be_fwd_reqs; /* number of send reqs through forwarding i/f */
u32 be_tx_wrbs; /* number of tx WRBs used */
- u32 be_tx_events; /* number of tx completion events */
u32 be_tx_compl; /* number of tx completion entries processed */
ulong be_tx_jiffies;
u64 be_tx_bytes;
u64 be_tx_bytes_prev;
+ u64 be_tx_pkts;
u32 be_tx_rate;
-
- u32 cache_barrier[16];
-
- u32 be_ethrx_post_fail;/* number of ethrx buffer alloc failures */
- u32 be_rx_polls; /* number of times NAPI called poll function */
- u32 be_rx_events; /* number of ucast rx completion events */
- u32 be_rx_compl; /* number of rx completion entries processed */
- ulong be_rx_jiffies;
- u64 be_rx_bytes;
- u64 be_rx_bytes_prev;
- u32 be_rx_rate;
- /* number of non ether type II frames dropped where
- * frame len > length field of Mac Hdr */
- u32 be_802_3_dropped_frames;
- /* number of non ether type II frames malformed where
- * in frame len < length field of Mac Hdr */
- u32 be_802_3_malformed_frames;
- u32 be_rxcp_err; /* Num rx completion entries w/ err set. */
- ulong rx_fps_jiffies; /* jiffies at last FPS calc */
- u32 be_rx_frags;
- u32 be_prev_rx_frags;
- u32 be_rx_fps; /* Rx frags per second */
-};
-
-struct be_stats_obj {
- struct be_drvr_stats drvr_stats;
- struct be_dma_mem cmd;
+ u32 be_ipv6_ext_hdr_tx_drop;
};
struct be_tx_obj {
@@ -199,23 +220,146 @@ struct be_tx_obj {
struct be_queue_info cq;
/* Remember the skbs that were transmitted */
struct sk_buff *sent_skb_list[TX_Q_LEN];
+ struct be_tx_stats stats;
};
/* Struct to remember the pages posted for rx frags */
struct be_rx_page_info {
struct page *page;
- dma_addr_t bus;
+ DECLARE_PCI_UNMAP_ADDR(bus);
u16 page_offset;
bool last_page_user;
};
+struct be_rx_stats {
+ u32 rx_post_fail;/* number of ethrx buffer alloc failures */
+ u32 rx_polls; /* number of times NAPI called poll function */
+ u32 rx_events; /* number of ucast rx completion events */
+ u32 rx_compl; /* number of rx completion entries processed */
+ ulong rx_drops_no_skbs; /* number of skb allocation errors */
+ ulong rx_jiffies;
+ u64 rx_bytes;
+ u64 rx_bytes_prev;
+ u64 rx_pkts;
+ u32 rx_rate;
+ u32 rx_mcast_pkts;
+ u32 rxcp_err; /* Num rx completion entries w/ err set. */
+ ulong rx_fps_jiffies; /* jiffies at last FPS calc */
+ u32 rx_frags;
+ u32 prev_rx_frags;
+ u32 rx_fps; /* Rx frags per second */
+ u32 rx_drops_no_frags;
+};
+
+struct be_rx_compl_info {
+ u32 rss_hash;
+ u16 vlan_tag;
+ u16 pkt_size;
+ u16 rxq_idx;
+ u16 port;
+ u8 vlanf;
+ u8 num_rcvd;
+ u8 err;
+ u8 ipf;
+ u8 tcpf;
+ u8 udpf;
+ u8 ip_csum;
+ u8 l4_csum;
+ u8 ipv6;
+ u8 vtm;
+ u8 pkt_type;
+};
+
struct be_rx_obj {
+ struct be_adapter *adapter;
struct be_queue_info q;
struct be_queue_info cq;
- struct be_rx_page_info page_info_tbl[RX_Q_LEN];
+ struct be_rx_compl_info rxcp;
+ struct be_rx_page_info *page_info_tbl;
+ struct net_lro_mgr lro_mgr;
+ struct net_lro_desc lro_desc[BE_MAX_LRO_DESCRIPTORS];
+ struct be_eq_obj rx_eq;
+ struct be_rx_stats stats;
+ u8 rss_id;
+ bool rx_post_starved; /* Zero rx frags have been posted to BE */
+ u16 prev_frag_idx;
+ u32 cache_line_barrier[16];
};
-#define BE_NUM_MSIX_VECTORS 2 /* 1 each for Tx and Rx */
+struct be_drv_stats {
+ u32 be_on_die_temperature;
+ u64 be_tx_events;
+ u64 eth_red_drops;
+ u64 rx_drops_no_pbuf;
+ u64 rx_drops_no_txpb;
+ u64 rx_drops_no_erx_descr;
+ u64 rx_drops_no_tpre_descr;
+ u64 rx_drops_too_many_frags;
+ u64 rx_drops_invalid_ring;
+ u64 forwarded_packets;
+ u64 rx_drops_mtu;
+ u64 rx_crc_errors;
+ u64 rx_alignment_symbol_errors;
+ u64 rx_pause_frames;
+ u64 rx_priority_pause_frames;
+ u64 rx_control_frames;
+ u64 rx_in_range_errors;
+ u64 rx_out_range_errors;
+ u64 rx_frame_too_long;
+ u64 rx_address_match_errors;
+ u64 rx_dropped_too_small;
+ u64 rx_dropped_too_short;
+ u64 rx_dropped_header_too_small;
+ u64 rx_dropped_tcp_length;
+ u64 rx_dropped_runt;
+ u64 rx_ip_checksum_errs;
+ u64 rx_tcp_checksum_errs;
+ u64 rx_udp_checksum_errs;
+ u64 rx_switched_unicast_packets;
+ u64 rx_switched_multicast_packets;
+ u64 rx_switched_broadcast_packets;
+ u64 tx_pauseframes;
+ u64 tx_priority_pauseframes;
+ u64 tx_controlframes;
+ u64 rxpp_fifo_overflow_drop;
+ u64 rx_input_fifo_overflow_drop;
+ u64 pmem_fifo_overflow_drop;
+ u64 jabber_events;
+};
+
+struct be_vf_cfg {
+ unsigned char vf_mac_addr[ETH_ALEN];
+ u32 vf_if_handle;
+ u32 vf_pmac_id;
+ u16 vf_def_vid;
+ u16 vf_vlan_tag;
+ u32 vf_tx_rate;
+};
+
+#define BE_INVALID_PMAC_ID 0xffffffff
+#define BE_FLAGS_DCBX (1 << 16)
+#define BE_UC_PMAC_COUNT 30
+#define BE_VF_UC_PMAC_COUNT 2
+
+#define BE_FLAGS_LINK_STATUS_INIT 1
+
+struct phy_info {
+ u8 transceiver;
+ u8 autoneg;
+ u8 fc_autoneg;
+ u8 port_type;
+ u16 phy_type;
+ u16 interface_type;
+ u32 misc_params;
+ u16 auto_speeds_supported;
+ u16 fixed_speeds_supported;
+ int link_speed;
+ int forced_port_speed;
+ u32 dac_cable_len;
+ u32 advertising;
+ u32 supported;
+};
+
struct be_adapter {
struct pci_dev *pdev;
struct net_device *netdev;
@@ -224,7 +368,7 @@ struct be_adapter {
u8 __iomem *db; /* Door Bell */
u8 __iomem *pcicfg; /* PCI config space */
- spinlock_t mbox_lock; /* For serializing mbox cmds to BE card */
+ struct mutex mbox_lock; /* For serializing mbox cmds to BE card */
struct be_dma_mem mbox_mem;
/* Mbox mem is adjusted to align to 16 bytes. The allocated addr
* is stored for freeing purpose */
@@ -234,73 +378,126 @@ struct be_adapter {
spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */
spinlock_t mcc_cq_lock;
- struct msix_entry msix_entries[BE_NUM_MSIX_VECTORS];
- bool msix_enabled;
+ struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS];
+ u32 num_msix_vec;
bool isr_registered;
/* TX Rings */
struct be_eq_obj tx_eq;
- struct be_tx_obj tx_obj;
+ struct be_tx_obj tx_obj[MAX_TX_QS];
+ u8 num_tx_qs;
+ u8 prio_tc_map[MAX_TX_QS]; /* prio_tc_map[prio] => tc-id */
+ u8 tc_txq_map[MAX_TX_QS]; /* tc_txq_map[tc-id] => txq index */
u32 cache_line_break[8];
/* Rx rings */
- struct be_eq_obj rx_eq;
- struct be_rx_obj rx_obj;
+ struct be_rx_obj rx_obj[MAX_RX_QS]; /* one default non-rss Q */
+ u32 num_rx_qs;
+
+ struct be_dma_mem stats_cmd;
+ struct net_device_stats net_stats;
+ struct be_drv_stats drv_stats;
u32 big_page_size; /* Compounded page size shared by rx wrbs */
- bool rx_post_starved; /* Zero rx frags have been posted to BE */
struct vlan_group *vlan_grp;
u16 vlans_added;
u16 max_vlans; /* Number of vlans supported */
u8 vlan_tag[VLAN_GROUP_ARRAY_LEN];
- struct be_dma_mem mc_cmd_mem;
+ u8 vlan_prio_bmap; /* Available priority BitMap */
+ u16 recommended_prio; /* Recommended Priority */
+ struct be_dma_mem rx_filter; /* Cmd DMA mem for rx-filter */
- struct be_stats_obj stats;
/* Work queue used to perform periodic tasks like getting statistics */
struct delayed_work work;
+ u16 work_counter;
- /* Ethtool knobs and info */
- bool rx_csum; /* BE card must perform rx-checksumming */
+ u32 flags;
+ bool rx_csum; /* BE card must perform rx-checksumming */
+ u32 max_rx_coal;
char fw_ver[FW_VER_LEN];
u32 if_handle; /* Used to configure filtering */
- u32 pmac_id; /* MAC addr handle used by BE card */
+ u32 *pmac_id; /* MAC addr handle used by BE card */
+ u32 beacon_state; /* for set_phys_id */
bool eeh_err;
- bool link_up;
u32 port_num;
+ u32 hba_port_num;
bool promiscuous;
- bool wol;
- u32 cap;
+ u32 function_mode;
+ u32 function_caps;
u32 rx_fc; /* Rx flow control */
u32 tx_fc; /* Tx flow control */
+ bool ue_detected;
+ bool stats_cmd_sent;
+ bool gro_supported;
u8 generation; /* BladeEngine ASIC generation */
- int link_speed;
- u8 port_type;
- u8 transceiver;
+ u32 flash_status;
+ struct completion flash_compl;
+
+ u8 eq_next_idx;
+ bool be3_native;
+ u16 num_vfs;
+ struct be_vf_cfg *vf_cfg;
+ u8 is_virtfn;
+ u16 pvid;
+ u32 sli_family;
+ u8 port_name[4];
+ struct phy_info phy;
+ char model_number[32];
+ /* For CENTOS */
+ uint32_t pci_state[16];
+ u8 wol_cap;
+ bool wol;
+ u32 max_pmac_cnt; /* Max secondary UC MACs programmable */
+ u32 uc_macs; /* Count of secondary UC MAC programmed */
+ u16 asic_rev;
+ u16 qnq_vid;
+ u16 qnq_async_evt;
};
/* BladeEngine Generation numbers */
#define BE_GEN2 2
#define BE_GEN3 3
-extern const struct ethtool_ops be_ethtool_ops;
+#define ON 1
+#define OFF 0
+#define lancer_chip(adapter) ((adapter->pdev->device == OC_DEVICE_ID3) || \
+ (adapter->pdev->device == OC_DEVICE_ID4))
+#define lancer_A0_chip(adapter) \
+ (adapter->sli_family == LANCER_A0_SLI_FAMILY)
-#define drvr_stats(adapter) (&adapter->stats.drvr_stats)
+extern struct ethtool_ops be_ethtool_ops;
-static inline unsigned int be_pci_func(struct be_adapter *adapter)
-{
- return PCI_FUNC(adapter->pdev->devfn);
-}
+#define msix_enabled(adapter) (adapter->num_msix_vec > 0)
+#define tx_stats(txo) (&txo->stats)
+#define rx_stats(rxo) (&rxo->stats)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
+#define BE_SET_NETDEV_OPS(netdev, ops) be_netdev_ops_init(netdev, ops)
+#else
#define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops)
+#endif
+
+#define for_all_rx_queues(adapter, rxo, i) \
+ for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs; \
+ i++, rxo++)
+
+/* Just skip the first default non-rss queue */
+#define for_all_rss_queues(adapter, rxo, i) \
+ for (i = 0, rxo = &adapter->rx_obj[i+1]; i < (adapter->num_rx_qs - 1);\
+ i++, rxo++)
+
+#define for_all_tx_queues(adapter, txo, i) \
+ for (i = 0, txo = &adapter->tx_obj[i]; i < adapter->num_tx_qs; \
+ i++, txo++)
#define PAGE_SHIFT_4K 12
#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
/* Returns number of pages spanned by the data starting at the given addr */
-#define PAGES_4K_SPANNED(_address, size) \
- ((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \
+#define PAGES_4K_SPANNED(_address, size) \
+ ((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \
(size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K))
/* Byte offset into the page corresponding to given address */
@@ -308,7 +505,7 @@ static inline unsigned int be_pci_func(s
((size_t)(addr) & (PAGE_SIZE_4K-1))
/* Returns bit offset within a DWORD of a bitfield */
-#define AMAP_BIT_OFFSET(_struct, field) \
+#define AMAP_BIT_OFFSET(_struct, field) \
(((size_t)&(((_struct *)0)->field))%32)
/* Returns the bit mask of the field that is NOT shifted into location. */
@@ -359,6 +556,11 @@ static inline void swap_dws(void *wrb, i
#endif /* __BIG_ENDIAN */
}
+static inline bool vlan_configured(struct be_adapter *adapter)
+{
+ return adapter->vlan_grp && adapter->vlans_added;
+}
+
static inline u8 is_tcp_pkt(struct sk_buff *skb)
{
u8 val = 0;
@@ -383,9 +585,91 @@ static inline u8 is_udp_pkt(struct sk_bu
return val;
}
+static inline bool is_ipv4_pkt(struct sk_buff *skb)
+{
+ return (skb->protocol == ntohs(ETH_P_IP) &&
+ ip_hdr(skb)->version == 4);
+}
+
+static inline u8 is_ipv6_ext_hdr(struct sk_buff *skb)
+{
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ if (ip_hdr(skb)->version == 6)
+ return ipv6_ext_hdr(ipv6_hdr(skb)->nexthdr);
+ else
+#endif
+ return 0;
+}
+
+static inline void be_check_sriov_fn_type(struct be_adapter *adapter)
+{
+ u32 sli_intf;
+
+ pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf);
+ adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0;
+}
+
+static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac)
+{
+ u32 addr;
+
+ addr = jhash(adapter->netdev->dev_addr, ETH_ALEN, 0);
+
+ mac[5] = (u8)(addr & 0xFF);
+ mac[4] = (u8)((addr >> 8) & 0xFF);
+ mac[3] = (u8)((addr >> 16) & 0xFF);
+ /* Use the OUI programmed in hardware */
+ memcpy(mac, adapter->netdev->dev_addr, 3);
+}
+
+static inline u16 be_get_tx_vlan_tag(struct be_adapter *adapter,
+ struct sk_buff *skb)
+{
+ u8 vlan_prio = 0;
+ u16 vlan_tag = 0;
+
+ vlan_tag = vlan_tx_tag_get(skb);
+ vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
+ /* If vlan priority provided by OS is NOT in available bmap */
+ if (!(adapter->vlan_prio_bmap & (1 << vlan_prio)))
+ vlan_tag = (vlan_tag & ~VLAN_PRIO_MASK) |
+ adapter->recommended_prio;
+
+ return vlan_tag;
+}
+
+#define be_physfn(adapter) (!adapter->is_virtfn)
+
+static inline bool be_is_wol_excluded(struct be_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+
+ if (!be_physfn(adapter))
+ return true;
+
+ switch (pdev->subsystem_device) {
+ case OC_SUBSYS_DEVICE_ID1:
+ case OC_SUBSYS_DEVICE_ID2:
+ case OC_SUBSYS_DEVICE_ID3:
+ case OC_SUBSYS_DEVICE_ID4:
+ return true;
+ default:
+ return false;
+ }
+}
+
extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
u16 num_popped);
-extern void be_link_status_update(struct be_adapter *adapter, bool link_up);
+extern void be_link_status_update(struct be_adapter *adapter, u8 link_status);
extern void netdev_stats_update(struct be_adapter *adapter);
+extern void be_parse_stats(struct be_adapter *adapter);
extern int be_load_fw(struct be_adapter *adapter, u8 *func);
+extern bool be_is_wol_supported(struct be_adapter *adapter);
+extern bool be_pause_supported(struct be_adapter *adapter);
+
+#ifdef CONFIG_PALAU
+extern void be_sysfs_create_group(struct be_adapter *adapter);
+extern void be_sysfs_remove_group(struct be_adapter *adapter);
+#endif
+
#endif /* BE_H */
diff -r 099b2caaa48c drivers/net/benet/be_cmds.c
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -1,30 +1,44 @@
/*
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2011 Emulex
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation. The full GNU General
+ * as published by the Free Software Foundation. The full GNU General
* Public License is included in this distribution in the file called COPYING.
*
* Contact Information:
*
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
*/
#include "be.h"
#include "be_cmds.h"
+/* Must be a power of 2 or else MODULO will BUG_ON */
+static int be_get_temp_freq = 64;
+
+static inline void *embedded_payload(struct be_mcc_wrb *wrb)
+{
+ return wrb->payload.embedded_payload;
+}
static void be_mcc_notify(struct be_adapter *adapter)
{
struct be_queue_info *mccq = &adapter->mcc_obj.q;
u32 val = 0;
+ if (adapter->eeh_err) {
+ dev_info(&adapter->pdev->dev, "Error in Card Detected! Cannot issue commands\n");
+ return;
+ }
+
val |= mccq->id & DB_MCCQ_RING_ID_MASK;
val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
+
+ wmb();
iowrite32(val, adapter->db + DB_MCCQ_OFFSET);
}
@@ -59,21 +73,76 @@ static int be_mcc_compl_process(struct b
compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
CQE_STATUS_COMPL_MASK;
+
+ if (((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) ||
+ (compl->tag0 == OPCODE_COMMON_WRITE_OBJECT)) &&
+ (compl->tag1 == CMD_SUBSYSTEM_COMMON)) {
+ adapter->flash_status = compl_status;
+ complete(&adapter->flash_compl);
+ }
+
if (compl_status == MCC_STATUS_SUCCESS) {
- if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) {
- struct be_cmd_resp_get_stats *resp =
- adapter->stats.cmd.va;
- be_dws_le_to_cpu(&resp->hw_stats,
- sizeof(resp->hw_stats));
+ if (((compl->tag0 == OPCODE_ETH_GET_STATISTICS) ||
+ (compl->tag0 == OPCODE_ETH_GET_PPORT_STATS)) &&
+ (compl->tag1 == CMD_SUBSYSTEM_ETH)) {
+ if (adapter->generation == BE_GEN3) {
+ if (lancer_chip(adapter)) {
+ struct lancer_cmd_resp_pport_stats
+ *resp = adapter->stats_cmd.va;
+ be_dws_le_to_cpu(&resp->pport_stats,
+ sizeof(resp->pport_stats));
+ } else {
+ struct be_cmd_resp_get_stats_v1 *resp =
+ adapter->stats_cmd.va;
+
+ be_dws_le_to_cpu(&resp->hw_stats,
+ sizeof(resp->hw_stats));
+ }
+ } else {
+ struct be_cmd_resp_get_stats_v0 *resp =
+ adapter->stats_cmd.va;
+
+ be_dws_le_to_cpu(&resp->hw_stats,
+ sizeof(resp->hw_stats));
+ }
+ be_parse_stats(adapter);
netdev_stats_update(adapter);
+ adapter->stats_cmd_sent = false;
}
- } else if (compl_status != MCC_STATUS_NOT_SUPPORTED) {
- extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
- CQE_STATUS_EXTD_MASK;
- dev_warn(&adapter->pdev->dev,
- "Error in cmd completion - opcode %d, compl %d, extd %d\n",
- compl->tag0, compl_status, extd_status);
+ if (compl->tag0 ==
+ OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES) {
+ struct be_mcc_wrb *mcc_wrb =
+ queue_index_node(&adapter->mcc_obj.q,
+ compl->tag1);
+ struct be_cmd_resp_get_cntl_addnl_attribs *resp =
+ embedded_payload(mcc_wrb);
+ adapter->drv_stats.be_on_die_temperature =
+ resp->on_die_temperature;
+ }
+ } else {
+ if (compl->tag1 == MCC_WRB_PASS_THRU)
+ goto done;
+
+ if (compl->tag0 == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES)
+ be_get_temp_freq = 0;
+
+ if (compl_status == MCC_STATUS_NOT_SUPPORTED ||
+ compl_status == MCC_STATUS_ILLEGAL_REQUEST)
+ goto done;
+
+ if (compl_status == MCC_STATUS_UNAUTHORIZED_REQUEST) {
+ dev_warn(&adapter->pdev->dev, "This domain(VM) is not "
+ "permitted to execute this cmd (opcode %d)\n",
+ compl->tag0);
+ } else {
+ extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
+ CQE_STATUS_EXTD_MASK;
+ dev_err(&adapter->pdev->dev, "Cmd (opcode %d) failed:"
+ "status %d, extd-status %d\n",
+ compl->tag0, compl_status, extd_status);
+ }
}
+done:
return compl_status;
}
@@ -81,8 +150,103 @@ static int be_mcc_compl_process(struct b
static void be_async_link_state_process(struct be_adapter *adapter,
struct be_async_event_link_state *evt)
{
- be_link_status_update(adapter,
- evt->port_link_status == ASYNC_EVENT_LINK_UP);
+ /* When link status changes, link speed must be re-queried from FW */
+ adapter->phy.link_speed = -1;
+
+ /* For the initial link status do not rely on the ASYNC event as
+ * it may not be received in some cases.
+ */
+ if (adapter->flags & BE_FLAGS_LINK_STATUS_INIT)
+ be_link_status_update(adapter, evt->port_link_status);
+}
+
+/* Grp5 CoS Priority evt */
+static void be_async_grp5_cos_priority_process(struct be_adapter *adapter,
+ struct be_async_event_grp5_cos_priority *evt)
+{
+ if (evt->valid) {
+ adapter->vlan_prio_bmap = evt->available_priority_bmap;
+ adapter->recommended_prio &= ~VLAN_PRIO_MASK;
+ adapter->recommended_prio =
+ evt->reco_default_priority << VLAN_PRIO_SHIFT;
+ }
+}
+
+static void be_async_qnq_event_process(struct be_adapter *adapter,
+ struct be_async_event_qnq *evt)
+{
+ if (evt->valid)
+ adapter->qnq_vid = le16_to_cpu(evt->vlan_tag);
+ adapter->qnq_async_evt = true;
+}
+
+/* Grp5 QOS Speed evt */
+static void be_async_grp5_qos_speed_process(struct be_adapter *adapter,
+ struct be_async_event_grp5_qos_link_speed *evt)
+{
+ if (evt->physical_port == adapter->hba_port_num) {
+ /* qos_link_speed is in units of 10 Mbps */
+ adapter->phy.link_speed = evt->qos_link_speed * 10;
+ }
+}
+
+/*Grp5 PVID evt*/
+static void be_async_grp5_pvid_state_process(struct be_adapter *adapter,
+ struct be_async_event_grp5_pvid_state *evt)
+{
+ if (evt->enabled)
+ adapter->pvid = le16_to_cpu(evt->tag) & VLAN_VID_MASK ;
+ else
+ adapter->pvid = 0;
+}
+
+static void be_async_grp5_evt_process(struct be_adapter *adapter,
+ u32 trailer, struct be_mcc_compl *evt)
+{
+ u8 event_type = 0;
+
+ event_type = (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) &
+ ASYNC_TRAILER_EVENT_TYPE_MASK;
+
+ switch (event_type) {
+ case ASYNC_EVENT_COS_PRIORITY:
+ be_async_grp5_cos_priority_process(adapter,
+ (struct be_async_event_grp5_cos_priority *)evt);
+ break;
+ case ASYNC_EVENT_QOS_SPEED:
+ be_async_grp5_qos_speed_process(adapter,
+ (struct be_async_event_grp5_qos_link_speed *)evt);
+ break;
+ case ASYNC_EVENT_PVID_STATE:
+ be_async_grp5_pvid_state_process(adapter,
+ (struct be_async_event_grp5_pvid_state *)evt);
+ break;
+ case GRP5_TYPE_PRIO_TC_MAP:
+ memcpy(adapter->prio_tc_map, evt, MAX_TX_QS);
+ break;
+ default:
+ printk(KERN_WARNING "Unknown grp5 event!\n");
+ break;
+ }
+}
+
+static void be_async_dbg_evt_process(struct be_adapter *adapter,
+ u32 trailer, struct be_mcc_compl *evt)
+{
+ u8 event_type = 0;
+
+ event_type = (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) &
+ ASYNC_TRAILER_EVENT_TYPE_MASK;
+
+ switch (event_type) {
+ case ASYNC_DEBUG_EVENT_TYPE_QNQ:
+ be_async_qnq_event_process(adapter,
+ (struct be_async_event_qnq *)evt);
+ break;
+ default:
+ dev_warn(&adapter->pdev->dev, "Unknown debug event\n");
+ break;
+ }
}
static inline bool is_link_state_evt(u32 trailer)
@@ -92,6 +256,20 @@ static inline bool is_link_state_evt(u32
ASYNC_EVENT_CODE_LINK_STATE);
}
+static inline bool is_grp5_evt(u32 trailer)
+{
+ return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
+ ASYNC_TRAILER_EVENT_CODE_MASK) ==
+ ASYNC_EVENT_CODE_GRP_5);
+}
+
+static inline bool is_dbg_evt(u32 trailer)
+{
+ return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
+ ASYNC_TRAILER_EVENT_CODE_MASK) ==
+ ASYNC_EVENT_CODE_DBG);
+}
+
static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
{
struct be_queue_info *mcc_cq = &adapter->mcc_obj.cq;
@@ -129,11 +307,19 @@ int be_process_mcc(struct be_adapter *ad
while ((compl = be_mcc_compl_get(adapter))) {
if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
/* Interpret flags as an async trailer */
- BUG_ON(!is_link_state_evt(compl->flags));
-
- /* Interpret compl as a async link evt */
- be_async_link_state_process(adapter,
+ if (is_link_state_evt(compl->flags))
+ be_async_link_state_process(adapter,
(struct be_async_event_link_state *) compl);
+ else if (is_grp5_evt(compl->flags))
+ be_async_grp5_evt_process(adapter,
+ compl->flags, compl);
+ else if (is_dbg_evt(compl->flags))
+ be_async_dbg_evt_process(adapter,
+ compl->flags, compl);
+ else
+ dev_warn(&adapter->pdev->dev,
+ "Unknown async event\n");
+
} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
*status = be_mcc_compl_process(adapter, compl);
atomic_dec(&mcc_obj->q.used);
@@ -153,6 +339,9 @@ static int be_mcc_wait_compl(struct be_a
int i, num, status = 0;
struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
+ if (adapter->eeh_err)
+ return -EIO;
+
for (i = 0; i < mcc_timeout; i++) {
num = be_process_mcc(adapter, &status);
if (num)
@@ -179,9 +368,13 @@ static int be_mcc_notify_wait(struct be_
static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
{
- int cnt = 0, wait = 5;
+ int msecs = 0;
u32 ready;
+ if (adapter->eeh_err) {
+ dev_err(&adapter->pdev->dev, "Error detected in card.Cannot issue commands\n");
+ return -EIO;
+ }
do {
ready = ioread32(db);
if (ready == 0xffffffff) {
@@ -194,15 +387,15 @@ static int be_mbox_db_ready_wait(struct
if (ready)
break;
- if (cnt > 4000000) {
+ if (msecs > 4000) {
dev_err(&adapter->pdev->dev, "mbox poll timed out\n");
+ be_detect_dump_ue(adapter);
return -1;
}
- if (cnt > 50)
- wait = 200;
- cnt += wait;
- udelay(wait);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(msecs_to_jiffies(1));
+ msecs++;
} while (true);
return 0;
@@ -260,7 +453,12 @@ static int be_mbox_notify_wait(struct be
static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage)
{
- u32 sem = ioread32(adapter->csr + MPU_EP_SEMAPHORE_OFFSET);
+ u32 sem;
+
+ if (lancer_chip(adapter))