diff --git a/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/default_sku b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/default_sku new file mode 100644 index 000000000000..bc4d84f9c0e2 --- /dev/null +++ b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/default_sku @@ -0,0 +1 @@ +fn-6254-dn-f t1 diff --git a/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/fn-6254-dn-f/port_config.ini b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/fn-6254-dn-f/port_config.ini new file mode 100755 index 000000000000..405e44cd9e0c --- /dev/null +++ b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/fn-6254-dn-f/port_config.ini @@ -0,0 +1,55 @@ +#name lanes alias index speed +Ethernet0 8 Ethernet1/1 0 25000 +Ethernet1 9 Ethernet2/1 1 25000 +Ethernet2 10 Ethernet3/1 2 25000 +Ethernet3 11 Ethernet4/1 3 25000 +Ethernet4 12 Ethernet5/1 4 25000 +Ethernet5 13 Ethernet6/1 5 25000 +Ethernet6 14 Ethernet7/1 6 25000 +Ethernet7 15 Ethernet8/1 7 25000 +Ethernet8 16 Ethernet9/1 8 25000 +Ethernet9 17 Ethernet10/1 9 25000 +Ethernet10 18 Ethernet11/1 10 25000 +Ethernet11 19 Ethernet12/1 11 25000 +Ethernet12 20 Ethernet13/1 12 25000 +Ethernet13 21 Ethernet14/1 13 25000 +Ethernet14 22 Ethernet15/1 14 25000 +Ethernet15 23 Ethernet16/1 15 25000 +Ethernet16 32 Ethernet17/1 16 25000 +Ethernet17 33 Ethernet18/1 17 25000 +Ethernet18 34 Ethernet19/1 18 25000 +Ethernet19 35 Ethernet20/1 19 25000 +Ethernet20 40 Ethernet21/1 20 25000 +Ethernet21 41 Ethernet22/1 21 25000 +Ethernet22 42 Ethernet23/1 22 25000 +Ethernet23 43 Ethernet24/1 23 25000 +Ethernet24 48 Ethernet25/1 24 25000 +Ethernet25 49 Ethernet26/1 25 25000 +Ethernet26 50 Ethernet27/1 26 25000 +Ethernet27 51 Ethernet28/1 27 25000 +Ethernet28 56 Ethernet29/1 28 25000 +Ethernet29 57 Ethernet30/1 29 25000 +Ethernet30 58 Ethernet31/1 30 25000 +Ethernet31 59 Ethernet32/1 31 25000 +Ethernet32 64 Ethernet33/1 32 25000 +Ethernet33 65 Ethernet34/1 33 25000 +Ethernet34 66 Ethernet35/1 34 25000 +Ethernet35 67 Ethernet36/1 35 25000 +Ethernet36 68 Ethernet37/1 36 25000 +Ethernet37 69 Ethernet38/1 37 25000 +Ethernet38 70 Ethernet39/1 38 25000 +Ethernet39 71 Ethernet40/1 39 25000 +Ethernet40 72 Ethernet41/1 40 25000 +Ethernet41 73 Ethernet42/1 41 25000 +Ethernet42 74 Ethernet43/1 42 25000 +Ethernet43 75 Ethernet44/1 43 25000 +Ethernet44 76 Ethernet45/1 44 25000 +Ethernet45 77 Ethernet46/1 45 25000 +Ethernet46 78 Ethernet47/1 46 25000 +Ethernet47 79 Ethernet48/1 47 25000 +Ethernet48 80,81,82,83 Ethernet49/1 48 100000 +Ethernet49 84,85,86,87 Ethernet50/1 49 100000 +Ethernet50 104,105,106,107 Ethernet51/1 50 100000 +Ethernet51 108,109,110,111 Ethernet52/1 51 100000 +Ethernet52 112,113,114,115 Ethernet53/1 52 100000 +Ethernet53 116,117,118,119 Ethernet54/1 53 100000 diff --git a/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/fn-6254-dn-f/sai.profile b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/fn-6254-dn-f/sai.profile new file mode 100755 index 000000000000..a7ca856a324a --- /dev/null +++ b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/fn-6254-dn-f/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/platform/tau-fn-6254-dn-f.cfg +SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/tau-fn-6254-dn-f.dsh diff --git a/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/fn-6254-dn-f/tau-fn-6254-dn-f.dsh b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/fn-6254-dn-f/tau-fn-6254-dn-f.dsh new file mode 100755 index 000000000000..98a0c8f4912e --- /dev/null +++ b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/fn-6254-dn-f/tau-fn-6254-dn-f.dsh @@ -0,0 +1,634 @@ +init start stage low-level + +init set port-map port=0 eth-macro=2 lane=0 max-speed=25g active=true +init set port-map port=1 eth-macro=2 lane=1 max-speed=25g active=true +init set port-map port=2 eth-macro=2 lane=2 max-speed=25g active=true +init set port-map port=3 eth-macro=2 lane=3 max-speed=25g active=true +init set port-map port=4 eth-macro=3 lane=0 max-speed=25g active=true +init set port-map port=5 eth-macro=3 lane=1 max-speed=25g active=true +init set port-map port=6 eth-macro=3 lane=2 max-speed=25g active=true +init set port-map port=7 eth-macro=3 lane=3 max-speed=25g active=true +init set port-map port=8 eth-macro=4 lane=0 max-speed=25g active=true +init set port-map port=9 eth-macro=4 lane=1 max-speed=25g active=true +init set port-map port=10 eth-macro=4 lane=2 max-speed=25g active=true +init set port-map port=11 eth-macro=4 lane=3 max-speed=25g active=true +init set port-map port=12 eth-macro=5 lane=0 max-speed=25g active=true +init set port-map port=13 eth-macro=5 lane=1 max-speed=25g active=true +init set port-map port=14 eth-macro=5 lane=2 max-speed=25g active=true +init set port-map port=15 eth-macro=5 lane=3 max-speed=25g active=true +init set port-map port=16 eth-macro=8 lane=0 max-speed=25g active=true +init set port-map port=17 eth-macro=8 lane=1 max-speed=25g active=true +init set port-map port=18 eth-macro=8 lane=2 max-speed=25g active=true +init set port-map port=19 eth-macro=8 lane=3 max-speed=25g active=true +init set port-map port=20 eth-macro=10 lane=0 max-speed=25g active=true +init set port-map port=21 eth-macro=10 lane=1 max-speed=25g active=true +init set port-map port=22 eth-macro=10 lane=2 max-speed=25g active=true +init set port-map port=23 eth-macro=10 lane=3 max-speed=25g active=true +init set port-map port=24 eth-macro=12 lane=0 max-speed=25g active=true +init set port-map port=25 eth-macro=12 lane=1 max-speed=25g active=true +init set port-map port=26 eth-macro=12 lane=2 max-speed=25g active=true +init set port-map port=27 eth-macro=12 lane=3 max-speed=25g active=true +init set port-map port=28 eth-macro=14 lane=0 max-speed=25g active=true +init set port-map port=29 eth-macro=14 lane=1 max-speed=25g active=true +init set port-map port=30 eth-macro=14 lane=2 max-speed=25g active=true +init set port-map port=31 eth-macro=14 lane=3 max-speed=25g active=true +init set port-map port=32 eth-macro=16 lane=0 max-speed=25g active=true +init set port-map port=33 eth-macro=16 lane=1 max-speed=25g active=true +init set port-map port=34 eth-macro=16 lane=2 max-speed=25g active=true +init set port-map port=35 eth-macro=16 lane=3 max-speed=25g active=true +init set port-map port=36 eth-macro=17 lane=0 max-speed=25g active=true +init set port-map port=37 eth-macro=17 lane=1 max-speed=25g active=true +init set port-map port=38 eth-macro=17 lane=2 max-speed=25g active=true +init set port-map port=39 eth-macro=17 lane=3 max-speed=25g active=true +init set port-map port=40 eth-macro=18 lane=0 max-speed=25g active=true +init set port-map port=41 eth-macro=18 lane=1 max-speed=25g active=true +init set port-map port=42 eth-macro=18 lane=2 max-speed=25g active=true +init set port-map port=43 eth-macro=18 lane=3 max-speed=25g active=true +init set port-map port=44 eth-macro=19 lane=0 max-speed=25g active=true +init set port-map port=45 eth-macro=19 lane=1 max-speed=25g active=true +init set port-map port=46 eth-macro=19 lane=2 max-speed=25g active=true +init set port-map port=47 eth-macro=19 lane=3 max-speed=25g active=true +init set port-map port=48 eth-macro=20 lane=0 max-speed=100g active=true +init set port-map port=49 eth-macro=21 lane=0 max-speed=100g active=true +init set port-map port=50 eth-macro=26 lane=0 max-speed=100g active=true +init set port-map port=51 eth-macro=27 lane=0 max-speed=100g active=true +init set port-map port=52 eth-macro=28 lane=0 max-speed=100g active=true +init set port-map port=53 eth-macro=29 lane=0 max-speed=100g active=true +init set port-map port=129 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true +init set port-map port=130 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true init-done=true + +init start stage task-rsrc +init start stage module +init start stage task +phy set lane-swap portlist=0 lane-cnt=1 property=tx data=0x00 +phy set lane-swap portlist=1 lane-cnt=1 property=tx data=0x01 +phy set lane-swap portlist=2 lane-cnt=1 property=tx data=0x02 +phy set lane-swap portlist=3 lane-cnt=1 property=tx data=0x03 + +phy set lane-swap portlist=4 lane-cnt=1 property=tx data=0x02 +phy set lane-swap portlist=5 lane-cnt=1 property=tx data=0x03 +phy set lane-swap portlist=6 lane-cnt=1 property=tx data=0x00 +phy set lane-swap portlist=7 lane-cnt=1 property=tx data=0x01 + +phy set lane-swap portlist=8 lane-cnt=1 property=tx data=0x00 +phy set lane-swap portlist=9 lane-cnt=1 property=tx data=0x01 +phy set lane-swap portlist=10 lane-cnt=1 property=tx data=0x02 +phy set lane-swap portlist=11 lane-cnt=1 property=tx data=0x03 + +phy set lane-swap portlist=12 lane-cnt=1 property=tx data=0x00 +phy set lane-swap portlist=13 lane-cnt=1 property=tx data=0x03 +phy set lane-swap portlist=14 lane-cnt=1 property=tx data=0x02 +phy set lane-swap portlist=15 lane-cnt=1 property=tx data=0x01 + +phy set lane-swap portlist=16 lane-cnt=1 property=tx data=0x03 +phy set lane-swap portlist=17 lane-cnt=1 property=tx data=0x02 +phy set lane-swap portlist=18 lane-cnt=1 property=tx data=0x01 +phy set lane-swap portlist=19 lane-cnt=1 property=tx data=0x00 + +phy set lane-swap portlist=20 lane-cnt=1 property=tx data=0x02 +phy set lane-swap portlist=21 lane-cnt=1 property=tx data=0x03 +phy set lane-swap portlist=22 lane-cnt=1 property=tx data=0x00 +phy set lane-swap portlist=23 lane-cnt=1 property=tx data=0x01 + +phy set lane-swap portlist=24 lane-cnt=1 property=tx data=0x02 +phy set lane-swap portlist=25 lane-cnt=1 property=tx data=0x03 +phy set lane-swap portlist=26 lane-cnt=1 property=tx data=0x00 +phy set lane-swap portlist=27 lane-cnt=1 property=tx data=0x01 + +phy set lane-swap portlist=28 lane-cnt=1 property=tx data=0x02 +phy set lane-swap portlist=29 lane-cnt=1 property=tx data=0x03 +phy set lane-swap portlist=30 lane-cnt=1 property=tx data=0x00 +phy set lane-swap portlist=31 lane-cnt=1 property=tx data=0x01 + +phy set lane-swap portlist=32 lane-cnt=1 property=tx data=0x00 +phy set lane-swap portlist=33 lane-cnt=1 property=tx data=0x01 +phy set lane-swap portlist=34 lane-cnt=1 property=tx data=0x02 +phy set lane-swap portlist=35 lane-cnt=1 property=tx data=0x03 + +phy set lane-swap portlist=36 lane-cnt=1 property=tx data=0x00 +phy set lane-swap portlist=37 lane-cnt=1 property=tx data=0x01 +phy set lane-swap portlist=38 lane-cnt=1 property=tx data=0x02 +phy set lane-swap portlist=39 lane-cnt=1 property=tx data=0x03 + +phy set lane-swap portlist=40 lane-cnt=1 property=tx data=0x00 +phy set lane-swap portlist=41 lane-cnt=1 property=tx data=0x01 +phy set lane-swap portlist=42 lane-cnt=1 property=tx data=0x02 +phy set lane-swap portlist=43 lane-cnt=1 property=tx data=0x03 + +phy set lane-swap portlist=44 lane-cnt=1 property=tx data=0x00 +phy set lane-swap portlist=45 lane-cnt=1 property=tx data=0x01 +phy set lane-swap portlist=46 lane-cnt=1 property=tx data=0x02 +phy set lane-swap portlist=47 lane-cnt=1 property=tx data=0x03 + +phy set lane-swap portlist=48 lane-cnt=4 property=tx data=0x03.02.01.00 +phy set lane-swap portlist=49 lane-cnt=4 property=tx data=0x01.02.03.00 +phy set lane-swap portlist=50 lane-cnt=4 property=tx data=0x01.02.03.00 +phy set lane-swap portlist=51 lane-cnt=4 property=tx data=0x03.02.01.00 +phy set lane-swap portlist=52 lane-cnt=4 property=tx data=0x03.02.01.00 +phy set lane-swap portlist=53 lane-cnt=4 property=tx data=0x01.02.03.00 + +phy set lane-swap portlist=129 lane-cnt=1 property=tx data=0x00 +phy set lane-swap portlist=130 lane-cnt=1 property=tx data=0x01 + +phy set lane-swap portlist=0 lane-cnt=1 property=rx data=0x00 +phy set lane-swap portlist=1 lane-cnt=1 property=rx data=0x01 +phy set lane-swap portlist=2 lane-cnt=1 property=rx data=0x02 +phy set lane-swap portlist=3 lane-cnt=1 property=rx data=0x03 + +phy set lane-swap portlist=4 lane-cnt=1 property=rx data=0x02 +phy set lane-swap portlist=5 lane-cnt=1 property=rx data=0x03 +phy set lane-swap portlist=6 lane-cnt=1 property=rx data=0x00 +phy set lane-swap portlist=7 lane-cnt=1 property=rx data=0x01 + +phy set lane-swap portlist=8 lane-cnt=1 property=rx data=0x00 +phy set lane-swap portlist=9 lane-cnt=1 property=rx data=0x01 +phy set lane-swap portlist=10 lane-cnt=1 property=rx data=0x02 +phy set lane-swap portlist=11 lane-cnt=1 property=rx data=0x03 + +phy set lane-swap portlist=12 lane-cnt=1 property=rx data=0x03 +phy set lane-swap portlist=13 lane-cnt=1 property=rx data=0x02 +phy set lane-swap portlist=14 lane-cnt=1 property=rx data=0x01 +phy set lane-swap portlist=15 lane-cnt=1 property=rx data=0x00 + +phy set lane-swap portlist=16 lane-cnt=1 property=rx data=0x00 +phy set lane-swap portlist=17 lane-cnt=1 property=rx data=0x03 +phy set lane-swap portlist=18 lane-cnt=1 property=rx data=0x02 +phy set lane-swap portlist=19 lane-cnt=1 property=rx data=0x01 + +phy set lane-swap portlist=20 lane-cnt=1 property=rx data=0x00 +phy set lane-swap portlist=21 lane-cnt=1 property=rx data=0x03 +phy set lane-swap portlist=22 lane-cnt=1 property=rx data=0x02 +phy set lane-swap portlist=23 lane-cnt=1 property=rx data=0x01 + +phy set lane-swap portlist=24 lane-cnt=1 property=rx data=0x00 +phy set lane-swap portlist=25 lane-cnt=1 property=rx data=0x03 +phy set lane-swap portlist=26 lane-cnt=1 property=rx data=0x02 +phy set lane-swap portlist=27 lane-cnt=1 property=rx data=0x01 + +phy set lane-swap portlist=28 lane-cnt=1 property=rx data=0x00 +phy set lane-swap portlist=29 lane-cnt=1 property=rx data=0x03 +phy set lane-swap portlist=30 lane-cnt=1 property=rx data=0x02 +phy set lane-swap portlist=31 lane-cnt=1 property=rx data=0x01 + +phy set lane-swap portlist=32 lane-cnt=1 property=rx data=0x02 +phy set lane-swap portlist=33 lane-cnt=1 property=rx data=0x01 +phy set lane-swap portlist=34 lane-cnt=1 property=rx data=0x00 +phy set lane-swap portlist=35 lane-cnt=1 property=rx data=0x03 + +phy set lane-swap portlist=36 lane-cnt=1 property=rx data=0x02 +phy set lane-swap portlist=37 lane-cnt=1 property=rx data=0x01 +phy set lane-swap portlist=38 lane-cnt=1 property=rx data=0x00 +phy set lane-swap portlist=39 lane-cnt=1 property=rx data=0x03 + +phy set lane-swap portlist=40 lane-cnt=1 property=rx data=0x02 +phy set lane-swap portlist=41 lane-cnt=1 property=rx data=0x01 +phy set lane-swap portlist=42 lane-cnt=1 property=rx data=0x00 +phy set lane-swap portlist=43 lane-cnt=1 property=rx data=0x03 + +phy set lane-swap portlist=44 lane-cnt=1 property=rx data=0x02 +phy set lane-swap portlist=45 lane-cnt=1 property=rx data=0x01 +phy set lane-swap portlist=46 lane-cnt=1 property=rx data=0x00 +phy set lane-swap portlist=47 lane-cnt=1 property=rx data=0x03 + +phy set lane-swap portlist=48 lane-cnt=4 property=rx data=0x03.00.01.02 +phy set lane-swap portlist=49 lane-cnt=4 property=rx data=0x03.00.01.02 +phy set lane-swap portlist=50 lane-cnt=4 property=rx data=0x03.01.02.00 +phy set lane-swap portlist=51 lane-cnt=4 property=rx data=0x03.02.01.00 +phy set lane-swap portlist=52 lane-cnt=4 property=rx data=0x03.02.01.00 +phy set lane-swap portlist=53 lane-cnt=4 property=rx data=0x00.01.02.03 + +phy set lane-swap portlist=129 lane-cnt=1 property=rx data=0x00 +phy set lane-swap portlist=130 lane-cnt=1 property=rx data=0x01 + +phy set polarity-rev portlist=0 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=1 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=2 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=3 lane-cnt=1 property=tx data=0x01 + +phy set polarity-rev portlist=4 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=5 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=6 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=7 lane-cnt=1 property=tx data=0x00 + +phy set polarity-rev portlist=8 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=9 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=10 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=11 lane-cnt=1 property=tx data=0x01 + +phy set polarity-rev portlist=12 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=13 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=14 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=15 lane-cnt=1 property=tx data=0x00 + +phy set polarity-rev portlist=16 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=17 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=18 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=19 lane-cnt=1 property=tx data=0x01 + +phy set polarity-rev portlist=20 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=21 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=22 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=23 lane-cnt=1 property=tx data=0x00 + +phy set polarity-rev portlist=24 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=25 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=26 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=27 lane-cnt=1 property=tx data=0x00 + +phy set polarity-rev portlist=28 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=29 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=30 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=31 lane-cnt=1 property=tx data=0x00 + +phy set polarity-rev portlist=32 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=33 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=34 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=35 lane-cnt=1 property=tx data=0x01 + +phy set polarity-rev portlist=36 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=37 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=38 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=39 lane-cnt=1 property=tx data=0x01 + +phy set polarity-rev portlist=40 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=41 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=42 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=43 lane-cnt=1 property=tx data=0x01 + +phy set polarity-rev portlist=44 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=45 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=46 lane-cnt=1 property=tx data=0x01 +phy set polarity-rev portlist=47 lane-cnt=1 property=tx data=0x01 + +phy set polarity-rev portlist=48 lane-cnt=4 property=tx data=0x00.01.00.00 +phy set polarity-rev portlist=49 lane-cnt=4 property=tx data=0x00.00.01.00 +phy set polarity-rev portlist=50 lane-cnt=4 property=tx data=0x01.00.01.01 +phy set polarity-rev portlist=51 lane-cnt=4 property=tx data=0x01.01.01.01 +phy set polarity-rev portlist=52 lane-cnt=4 property=tx data=0x01.00.00.00 +phy set polarity-rev portlist=53 lane-cnt=4 property=tx data=0x00.00.01.00 + +phy set polarity-rev portlist=129 lane-cnt=1 property=tx data=0x00 +phy set polarity-rev portlist=130 lane-cnt=1 property=tx data=0x00 + +phy set polarity-rev portlist=0 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=1 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=2 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=3 lane-cnt=1 property=rx data=0x01 + +phy set polarity-rev portlist=4 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=5 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=6 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=7 lane-cnt=1 property=rx data=0x01 + +phy set polarity-rev portlist=8 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=9 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=10 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=11 lane-cnt=1 property=rx data=0x01 + +phy set polarity-rev portlist=12 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=13 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=14 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=15 lane-cnt=1 property=rx data=0x01 + +phy set polarity-rev portlist=16 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=17 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=18 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=19 lane-cnt=1 property=rx data=0x01 + +phy set polarity-rev portlist=20 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=21 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=22 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=23 lane-cnt=1 property=rx data=0x01 + +phy set polarity-rev portlist=24 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=25 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=26 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=27 lane-cnt=1 property=rx data=0x01 + +phy set polarity-rev portlist=28 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=29 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=30 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=31 lane-cnt=1 property=rx data=0x01 + +phy set polarity-rev portlist=32 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=33 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=34 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=35 lane-cnt=1 property=rx data=0x00 + +phy set polarity-rev portlist=36 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=37 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=38 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=39 lane-cnt=1 property=rx data=0x00 + +phy set polarity-rev portlist=40 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=41 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=42 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=43 lane-cnt=1 property=rx data=0x00 + +phy set polarity-rev portlist=44 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=45 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=46 lane-cnt=1 property=rx data=0x01 +phy set polarity-rev portlist=47 lane-cnt=1 property=rx data=0x00 + +phy set polarity-rev portlist=48 lane-cnt=4 property=rx data=0x00.01.00.00 +phy set polarity-rev portlist=49 lane-cnt=4 property=rx data=0x00.00.01.00 +phy set polarity-rev portlist=50 lane-cnt=4 property=rx data=0x00.00.01.01 +phy set polarity-rev portlist=51 lane-cnt=4 property=rx data=0x00.01.00.01 +phy set polarity-rev portlist=52 lane-cnt=4 property=rx data=0x00.01.00.01 +phy set polarity-rev portlist=53 lane-cnt=4 property=rx data=0x01.01.01.01 + +phy set polarity-rev portlist=129 lane-cnt=1 property=rx data=0x00 +phy set polarity-rev portlist=130 lane-cnt=1 property=rx data=0x00 + + +phy set pre-emphasis portlist=0 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=0 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=0 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=0 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=1 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=1 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=1 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=1 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=2 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=2 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=2 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=2 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=3 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=3 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=3 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=3 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=4 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=4 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=4 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=4 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=5 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=5 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=5 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=5 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=6 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=6 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=6 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=6 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=7 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=7 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=7 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=7 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=8 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=8 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=8 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=8 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=9 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=9 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=9 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=9 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=10 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=10 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=10 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=10 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=11 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=11 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=11 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=11 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=12 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=12 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=12 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=12 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=13 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=13 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=13 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=13 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=14 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=14 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=14 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=14 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=15 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=15 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=15 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=15 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=16 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=16 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=16 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=16 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=17 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=17 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=17 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=17 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=18 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=18 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=18 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=18 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=19 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=19 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=19 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=19 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=20 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=20 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=20 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=20 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=21 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=21 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=21 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=21 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=22 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=22 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=22 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=22 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=23 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=23 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=23 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=23 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=24 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=24 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=24 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=24 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=25 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=25 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=25 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=25 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=26 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=26 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=26 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=26 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=27 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=27 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=27 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=27 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=28 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=28 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=28 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=28 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=29 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=29 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=29 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=29 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=30 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=30 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=30 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=30 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=31 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=31 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=31 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=31 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=32 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=32 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=32 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=32 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=33 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=33 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=33 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=33 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=34 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=34 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=34 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=34 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=35 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=35 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=35 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=35 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=36 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=36 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=36 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=36 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=37 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=37 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=37 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=37 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=38 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=38 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=38 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=38 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=39 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=39 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=39 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=39 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=40 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=40 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=40 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=40 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=41 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=41 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=41 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=41 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=42 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=42 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=42 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=42 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=43 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=43 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=43 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=43 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=44 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=44 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=44 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=44 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=45 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=45 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=45 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=45 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=46 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=46 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=46 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=46 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=47 lane-cnt=1 property=c0 data=0x1d +phy set pre-emphasis portlist=47 lane-cnt=1 property=c1 data=0x7 +phy set pre-emphasis portlist=47 lane-cnt=1 property=cn1 data=0x0 +phy set pre-emphasis portlist=47 lane-cnt=1 property=c2 data=0x0 + +phy set pre-emphasis portlist=48 lane-cnt=4 property=c0 data=0x1d.1d.1d.1d +phy set pre-emphasis portlist=48 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set pre-emphasis portlist=48 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=48 lane-cnt=4 property=c2 data=0x0.0.0.0 + +phy set pre-emphasis portlist=49 lane-cnt=4 property=c0 data=0x1b.1d.1b.1d +phy set pre-emphasis portlist=49 lane-cnt=4 property=c1 data=0x9.7.9.7 +phy set pre-emphasis portlist=49 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=49 lane-cnt=4 property=c2 data=0x0.0.0.0 + +phy set pre-emphasis portlist=50 lane-cnt=4 property=c0 data=0x1d.1d.1d.1d +phy set pre-emphasis portlist=50 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set pre-emphasis portlist=50 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=50 lane-cnt=4 property=c2 data=0x0.0.0.0 + +phy set pre-emphasis portlist=51 lane-cnt=4 property=c0 data=0x1d.1d.1d.1d +phy set pre-emphasis portlist=51 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set pre-emphasis portlist=51 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=51 lane-cnt=4 property=c2 data=0x0.0.0.0 + +phy set pre-emphasis portlist=52 lane-cnt=4 property=c0 data=0x1d.1d.1d.1d +phy set pre-emphasis portlist=52 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set pre-emphasis portlist=52 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=52 lane-cnt=4 property=c2 data=0x0.0.0.0 + +phy set pre-emphasis portlist=53 lane-cnt=4 property=c0 data=0x1d.1d.1d.1d +phy set pre-emphasis portlist=53 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set pre-emphasis portlist=53 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=53 lane-cnt=4 property=c2 data=0x0.0.0.0 + +phy set pre-emphasis portlist=129 lane-cnt=1 property=c2 data=0x01 +phy set pre-emphasis portlist=129 lane-cnt=1 property=cn1 data=0x01 +phy set pre-emphasis portlist=129 lane-cnt=1 property=c1 data=0x03 +phy set pre-emphasis portlist=129 lane-cnt=1 property=c0 data=0x02 + +phy set pre-emphasis portlist=130 lane-cnt=1 property=c2 data=0x01 +phy set pre-emphasis portlist=130 lane-cnt=1 property=cn1 data=0x01 +phy set pre-emphasis portlist=130 lane-cnt=1 property=c1 data=0x03 +phy set pre-emphasis portlist=130 lane-cnt=1 property=c0 data=0x02 + +port set property portlist=0-47 speed=25g +port set property portlist=48-52,53 speed=100g +port set property portlist=129-130 speed=10g +port set property portlist=0-47 medium-type=sr +port set property portlist=48-52,53 medium-type=sr4 +port set property portlist=129-130 medium-type=kr +port set property portlist=0-53 fec=disable +port set adver portlist=129-130 speed-10g-kr +port set property portlist=129-130 an=enable +port set property portlist=0-53 admin=disable +port set property portlist=129-130 admin=enable diff --git a/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/installer.conf b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/installer.conf new file mode 100755 index 000000000000..925a32fc0c3a --- /dev/null +++ b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 diff --git a/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/plugins/eeprom.py b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/plugins/eeprom.py new file mode 100755 index 000000000000..6964c6bade4f --- /dev/null +++ b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/plugins/eeprom.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/4-0054/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/plugins/psuutil.py b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/plugins/psuutil.py new file mode 100755 index 000000000000..a23a7b7fe73e --- /dev/null +++ b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/plugins/psuutil.py @@ -0,0 +1,92 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + SYSFS_PSU_DIR = "/sys/bus/i2c/devices/7-0075" + + def __init__(self): + PsuBase.__init__(self) + + + # Get sysfs attribute + def get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip('\r\n') + + fd.close() + return retval + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + status = 0 + attr_file = 'psu_'+str(index)+'_status' + attr_path = self.SYSFS_PSU_DIR +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU status + if (attr_value == 1): + status = 1 + + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + attr_file = 'psu_'+str(index)+'_present' + attr_path = self.SYSFS_PSU_DIR +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU presence + if (attr_value == 0): + status = 1 + + return status + diff --git a/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/plugins/sfputil.py b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/plugins/sfputil.py new file mode 100755 index 000000000000..9238d0f06fde --- /dev/null +++ b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/plugins/sfputil.py @@ -0,0 +1,247 @@ +#!/usr/bin/env python + +try: + import os + import re + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class SfpUtil(SfpUtilBase): + """Platform specific sfputil class""" + + port_start = 0 + port_end = 53 + ports_in_block = 54 + cplda_sfp_num = 24 + cpldb_sfp_num = 12 + cpldc_sfp_num = 18 + + port_to_eeprom_mapping = {} + port_to_i2c_mapping = {} + sfp_ports = range(0, ports_in_block) + qsfp_ports = range(ports_in_block - 6, ports_in_block) + + + def __init__(self): + for x in range(self.port_start, self.port_end + 1): + if x < self.cpldb_sfp_num: + self.port_to_i2c_mapping.update({x:7}) + elif x < self.cplda_sfp_num + self.cpldb_sfp_num: + self.port_to_i2c_mapping.update({x:6}) + else: + self.port_to_i2c_mapping.update({x:8}) + + for x in range(self.port_start, self.port_end+1): + eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp'+str(x+1)+'_eeprom' + port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) + self.port_to_eeprom_mapping[x] = port_eeprom_path + SfpUtilBase.__init__(self) + + + def get_presence(self, port_num): + if port_num < self.port_start or port_num > self.port_end: + return False + + if port_num < self.cpldb_sfp_num: + presence_path = '/sys/bus/i2c/devices/7-0075/sfp'+str(port_num+1)+'_present' + elif port_num < self.cpldb_sfp_num + self.cplda_sfp_num: + presence_path = '/sys/bus/i2c/devices/6-0074/sfp'+str(port_num+1)+'_present' + else: + presence_path = '/sys/bus/i2c/devices/8-0076/sfp'+str(port_num+1)+'_present' + + try: + file = open(presence_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + value = int(file.readline().rstrip()) + + file.close() + if value == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + if port_num not in self.qsfp_ports: + return False + + lowpower_path = '/sys/bus/i2c/devices/8-0076/sfp'+str(port_num+1)+'_lowpower' + + try: + file = open(lowpower_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + value = int(file.readline().rstrip()) + + file.close() + if value == 1: + return True + + return False + + def set_low_power_mode(self, port_num, lpmode): + if port_num not in self.qsfp_ports: + return False + + lowpower_path = '/sys/bus/i2c/devices/8-0076/sfp'+str(port_num+1)+'_lowpower' + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + value = 1 + else: + value = 0 + + try: + file = open(lowpower_path, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + file.seek(0) + file.write(str(value)) + file.close() + + return True + + def reset(self, port_num): + if port_num not in self.qsfp_ports: + return False + reset_path = '/sys/bus/i2c/devices/8-0076/sfp'+str(port_num+1)+'_reset' + + try: + file = open(reset_path, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + file.seek(0) + file.write(str(2)) + file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + + try: + file = open(reset_path, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + file.seek(0) + file.write(str(1)) + file.close() + + return True + + def read_porttab_mappings(self, porttabfile): + logical = [] + logical_to_bcm = {} + logical_to_physical = {} + physical_to_logical = {} + last_fp_port_index = 0 + last_portname = "" + first = 1 + port_pos_in_file = 0 + parse_fmt_port_config_ini = False + + try: + f = open(porttabfile) + except: + raise + + parse_fmt_port_config_ini = (os.path.basename(porttabfile) == "port_config.ini") + + # Read the porttab file and generate dicts + # with mapping for future reference. + # XXX: move the porttab + # parsing stuff to a separate module, or reuse + # if something already exists + for line in f: + line.strip() + if re.search("^#", line) is not None: + continue + + # Parsing logic for 'port_config.ini' file + if (parse_fmt_port_config_ini): + # bcm_port is not explicitly listed in port_config.ini format + # Currently we assume ports are listed in numerical order according to bcm_port + # so we use the port's position in the file (zero-based) as bcm_port + portname = line.split()[0] + + bcm_port = str(port_pos_in_file) + + if len(line.split()) >= 4: + fp_port_index = int(line.split()[3]) + else: + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))/4 + else: # Parsing logic for older 'portmap.ini' file + (portname, bcm_port) = line.split("=")[1].split(",")[:2] + + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))/4 + + #Peter remove - 2018.04.13, this will cause can't show qsfp module when sfp_pot was set + #if ((len(self.sfp_ports) > 0) and (fp_port_index not in self.sfp_ports)): + #continue + + if first == 1: + # Initialize last_[physical|logical]_port + # to the first valid port + last_fp_port_index = fp_port_index + last_portname = portname + first = 0 + + logical.append(portname) + + logical_to_bcm[portname] = "xe" + bcm_port + logical_to_physical[portname] = [fp_port_index] + if physical_to_logical.get(fp_port_index) is None: + physical_to_logical[fp_port_index] = [portname] + else: + physical_to_logical[fp_port_index].append( + portname) + + if (fp_port_index - last_fp_port_index) > 1: + # last port was a gang port + for p in range(last_fp_port_index+1, fp_port_index): + logical_to_physical[last_portname].append(p) + if physical_to_logical.get(p) is None: + physical_to_logical[p] = [last_portname] + else: + physical_to_logical[p].append(last_portname) + + last_fp_port_index = fp_port_index + last_portname = portname + + port_pos_in_file += 1 + + self.logical = logical + self.logical_to_bcm = logical_to_bcm + self.logical_to_physical = logical_to_physical + self.physical_to_logical = physical_to_logical + + """ + print "logical: " + self.logical + print "logical to bcm: " + self.logical_to_bcm + print "logical to physical: " + self.logical_to_physical + print "physical to logical: " + self.physical_to_logical + """ + + def get_transceiver_change_event(self): + """ + TODO: This function need to be implemented + when decide to support monitoring SFP(Xcvrd) + on this platform. + """ + raise NotImplementedError + + + diff --git a/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/tau-fn-6254-dn-f.cfg b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/tau-fn-6254-dn-f.cfg new file mode 100755 index 000000000000..bbd7c8f80ff5 --- /dev/null +++ b/device/pegatron/x86_64-pegatron_fn_6254_dn_f-r0/tau-fn-6254-dn-f.cfg @@ -0,0 +1,23 @@ +#This configuration file is for customer init value feature. Please refer to mtk_cfg.h/mtk_cfg.c for detail. +#1. The lines beginning with # are comment lines. The lines beginning with number are the setting lines. +#2. There are five parameters which can be set. +# 1) the first is unit. +# 2) the second is NPS_CFG_TYPE_XXX. Refer to NPS_CFG_TYPE_T. +# 3) the 3-5 are {param0, param1, value} pairs. Refer to NPS_CFG_VALUE_T. Support HEX format. +# 4) the (unit, NPS_CFG_TYPE_XXX, param0, param1) group is the key to get the correspingding value. +# There should be no same (unit, NPS_CFG_TYPE_XXX, param0, param1) group. +#3. User must follow correct format to apply the setting. Please refer to below commentted example(#0 NPS_CFG_TYPE_L2_ADDR_MODE 0 0 1); +#4. Usage under the linux shell: +# 1) ./image-path/image-name -c cfg-path/NPS_Ari_EVB_24.cfg : mamually specify directory path if they are not in current work dirctory. +# 2) ./image-name -c NPS_Ari_EVB_24.cfg : the image and the NPS_Ari_EVB_24.cfg are in the current work directory. + +#unit NPS_CFG_TYPE_XXX param0 param1 value +#---- ---------------- ------ ------ ----- +0 NPS_CFG_TYPE_USE_UNIT_PORT 0 0 1 +0 NPS_CFG_TYPE_LED_CFG 0 0 3 +0 NPS_CFG_TYPE_CPI_PORT_MODE 129 0 1 +0 NPS_CFG_TYPE_CPI_PORT_MODE 130 0 1 +0 NPS_CFG_TYPE_USER_BUF_CTRL 0 0 1 +0 NPS_CFG_TYPE_HASH_L2_FDB_REGION_ENTRY_NUM 0 0 49152 +0 NPS_CFG_TYPE_HASH_L3_WITH_IPV6_PREFIX_64_REGION_ENTRY_NUM 0 0 32768 + diff --git a/device/pegatron/x86_64-pegatron_porsche-r0/plugins/sfputil.py b/device/pegatron/x86_64-pegatron_porsche-r0/plugins/sfputil.py index 28909f00110c..bfb6b590e43b 100755 --- a/device/pegatron/x86_64-pegatron_porsche-r0/plugins/sfputil.py +++ b/device/pegatron/x86_64-pegatron_porsche-r0/plugins/sfputil.py @@ -188,8 +188,9 @@ def read_porttab_mappings(self, porttabfile): fp_port_index = portname.split("Ethernet").pop() fp_port_index = int(fp_port_index.split("s").pop(0))/4 - if ((len(self.sfp_ports) > 0) and (fp_port_index not in self.sfp_ports)): - continue + #Peter remove - 2018.04.13, this will cause can't show qsfp module when sfp_pot was set + #if ((len(self.sfp_ports) > 0) and (fp_port_index not in self.sfp_ports)): + #continue if first == 1: # Initialize last_[physical|logical]_port @@ -233,6 +234,14 @@ def read_porttab_mappings(self, porttabfile): print "logical to physical: " + self.logical_to_physical print "physical to logical: " + self.physical_to_logical """ + + def get_transceiver_change_event(self): + """ + TODO: This function need to be implemented + when decide to support monitoring SFP(Xcvrd) + on this platform. + """ + raise NotImplementedError diff --git a/device/pegatron/x86_64-pegatron_porsche-r0/porsche/port_config.ini b/device/pegatron/x86_64-pegatron_porsche-r0/porsche/port_config.ini index 15fc60375941..405e44cd9e0c 100755 --- a/device/pegatron/x86_64-pegatron_porsche-r0/porsche/port_config.ini +++ b/device/pegatron/x86_64-pegatron_porsche-r0/porsche/port_config.ini @@ -1,52 +1,52 @@ #name lanes alias index speed -Ethernet0 8 Ethernet1/1 0 10000 -Ethernet1 9 Ethernet2/1 1 10000 -Ethernet2 10 Ethernet3/1 2 10000 -Ethernet3 11 Ethernet4/1 3 10000 -Ethernet4 12 Ethernet5/1 4 10000 -Ethernet5 13 Ethernet6/1 5 10000 -Ethernet6 14 Ethernet7/1 6 10000 -Ethernet7 15 Ethernet8/1 7 10000 -Ethernet8 16 Ethernet9/1 8 10000 -Ethernet9 17 Ethernet10/1 9 10000 -Ethernet10 18 Ethernet11/1 10 10000 -Ethernet11 19 Ethernet12/1 11 10000 -Ethernet12 20 Ethernet13/1 12 10000 -Ethernet13 21 Ethernet14/1 13 10000 -Ethernet14 22 Ethernet15/1 14 10000 -Ethernet15 23 Ethernet16/1 15 10000 -Ethernet16 32 Ethernet17/1 16 10000 -Ethernet17 33 Ethernet18/1 17 10000 -Ethernet18 34 Ethernet19/1 18 10000 -Ethernet19 35 Ethernet20/1 19 10000 -Ethernet20 40 Ethernet21/1 20 10000 -Ethernet21 41 Ethernet22/1 21 10000 -Ethernet22 42 Ethernet23/1 22 10000 -Ethernet23 43 Ethernet24/1 23 10000 -Ethernet24 48 Ethernet25/1 24 10000 -Ethernet25 49 Ethernet26/1 25 10000 -Ethernet26 50 Ethernet27/1 26 10000 -Ethernet27 51 Ethernet28/1 27 10000 -Ethernet28 56 Ethernet29/1 28 10000 -Ethernet29 57 Ethernet30/1 29 10000 -Ethernet30 58 Ethernet31/1 30 10000 -Ethernet31 59 Ethernet32/1 31 10000 -Ethernet32 64 Ethernet33/1 32 10000 -Ethernet33 65 Ethernet34/1 33 10000 -Ethernet34 66 Ethernet35/1 34 10000 -Ethernet35 67 Ethernet36/1 35 10000 -Ethernet36 68 Ethernet37/1 36 10000 -Ethernet37 69 Ethernet38/1 37 10000 -Ethernet38 70 Ethernet39/1 38 10000 -Ethernet39 71 Ethernet40/1 39 10000 -Ethernet40 72 Ethernet41/1 40 10000 -Ethernet41 73 Ethernet42/1 41 10000 -Ethernet42 74 Ethernet43/1 42 10000 -Ethernet43 75 Ethernet44/1 43 10000 -Ethernet44 76 Ethernet45/1 44 10000 -Ethernet45 77 Ethernet46/1 45 10000 -Ethernet46 78 Ethernet47/1 46 10000 -Ethernet47 79 Ethernet48/1 47 10000 +Ethernet0 8 Ethernet1/1 0 25000 +Ethernet1 9 Ethernet2/1 1 25000 +Ethernet2 10 Ethernet3/1 2 25000 +Ethernet3 11 Ethernet4/1 3 25000 +Ethernet4 12 Ethernet5/1 4 25000 +Ethernet5 13 Ethernet6/1 5 25000 +Ethernet6 14 Ethernet7/1 6 25000 +Ethernet7 15 Ethernet8/1 7 25000 +Ethernet8 16 Ethernet9/1 8 25000 +Ethernet9 17 Ethernet10/1 9 25000 +Ethernet10 18 Ethernet11/1 10 25000 +Ethernet11 19 Ethernet12/1 11 25000 +Ethernet12 20 Ethernet13/1 12 25000 +Ethernet13 21 Ethernet14/1 13 25000 +Ethernet14 22 Ethernet15/1 14 25000 +Ethernet15 23 Ethernet16/1 15 25000 +Ethernet16 32 Ethernet17/1 16 25000 +Ethernet17 33 Ethernet18/1 17 25000 +Ethernet18 34 Ethernet19/1 18 25000 +Ethernet19 35 Ethernet20/1 19 25000 +Ethernet20 40 Ethernet21/1 20 25000 +Ethernet21 41 Ethernet22/1 21 25000 +Ethernet22 42 Ethernet23/1 22 25000 +Ethernet23 43 Ethernet24/1 23 25000 +Ethernet24 48 Ethernet25/1 24 25000 +Ethernet25 49 Ethernet26/1 25 25000 +Ethernet26 50 Ethernet27/1 26 25000 +Ethernet27 51 Ethernet28/1 27 25000 +Ethernet28 56 Ethernet29/1 28 25000 +Ethernet29 57 Ethernet30/1 29 25000 +Ethernet30 58 Ethernet31/1 30 25000 +Ethernet31 59 Ethernet32/1 31 25000 +Ethernet32 64 Ethernet33/1 32 25000 +Ethernet33 65 Ethernet34/1 33 25000 +Ethernet34 66 Ethernet35/1 34 25000 +Ethernet35 67 Ethernet36/1 35 25000 +Ethernet36 68 Ethernet37/1 36 25000 +Ethernet37 69 Ethernet38/1 37 25000 +Ethernet38 70 Ethernet39/1 38 25000 +Ethernet39 71 Ethernet40/1 39 25000 +Ethernet40 72 Ethernet41/1 40 25000 +Ethernet41 73 Ethernet42/1 41 25000 +Ethernet42 74 Ethernet43/1 42 25000 +Ethernet43 75 Ethernet44/1 43 25000 +Ethernet44 76 Ethernet45/1 44 25000 +Ethernet45 77 Ethernet46/1 45 25000 +Ethernet46 78 Ethernet47/1 46 25000 +Ethernet47 79 Ethernet48/1 47 25000 Ethernet48 80,81,82,83 Ethernet49/1 48 100000 Ethernet49 84,85,86,87 Ethernet50/1 49 100000 Ethernet50 104,105,106,107 Ethernet51/1 50 100000 diff --git a/device/pegatron/x86_64-pegatron_porsche-r0/porsche/tau-porsche.dsh b/device/pegatron/x86_64-pegatron_porsche-r0/porsche/tau-porsche.dsh index b370fe83b837..5e6d4cd5a6dd 100755 --- a/device/pegatron/x86_64-pegatron_porsche-r0/porsche/tau-porsche.dsh +++ b/device/pegatron/x86_64-pegatron_porsche-r0/porsche/tau-porsche.dsh @@ -1,52 +1,52 @@ init start stage unit=0 low-level -init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=10g active=true -init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=10g active=true -init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=10g active=true -init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=10g active=true -init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=10g active=true -init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=10g active=true -init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=10g active=true -init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=10g active=true -init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=10g active=true -init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=10g active=true -init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=10g active=true -init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=10g active=true -init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=10g active=true -init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=10g active=true -init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=10g active=true -init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=10g active=true -init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=10g active=true -init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=10g active=true -init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=10g active=true -init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=10g active=true -init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=10g active=true -init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=10g active=true -init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=10g active=true -init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=10g active=true -init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=10g active=true -init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=10g active=true -init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=10g active=true -init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=10g active=true -init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=10g active=true -init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=10g active=true -init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=10g active=true -init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=10g active=true -init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=10g active=true -init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=10g active=true -init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=10g active=true -init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=10g active=true -init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=10g active=true -init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=10g active=true -init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=10g active=true -init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=10g active=true -init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=10g active=true -init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=10g active=true -init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=10g active=true -init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=10g active=true -init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=10g active=true -init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=10g active=true -init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=10g active=true -init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=10g active=true +init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true +init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true +init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true +init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true +init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true +init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true +init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true +init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true +init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true +init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true +init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true +init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true +init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true +init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true +init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true +init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true +init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true +init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true +init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true +init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true +init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true +init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true +init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true +init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true +init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true +init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true +init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true +init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true +init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true +init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true +init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true +init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true +init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true +init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true +init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true +init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true +init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true +init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true +init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true +init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true +init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true +init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true +init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true +init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true +init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true +init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true +init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true +init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true init set port-map unit=0 port=48 eth-macro=20 lane=0 max-speed=100g active=true init set port-map unit=0 port=49 eth-macro=21 lane=0 max-speed=100g active=true init set port-map unit=0 port=50 eth-macro=26 lane=0 max-speed=100g active=true @@ -488,7 +488,7 @@ phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x02.02.02.0 phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x00.00.00.00 phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1A.1A.1A.1A phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x07.07.07.07 -port set property unit=0 portlist=0-47 speed=10g +port set property unit=0 portlist=0-47 speed=25g port set property unit=0 portlist=0-47 medium-type=sr port set property unit=0 portlist=48-53 speed=100g port set property unit=0 portlist=48-53 medium-type=sr4 diff --git a/platform/nephos/one-image.mk b/platform/nephos/one-image.mk index d29d0e8c9350..ad45faaa65b6 100644 --- a/platform/nephos/one-image.mk +++ b/platform/nephos/one-image.mk @@ -5,8 +5,9 @@ $(SONIC_ONE_IMAGE)_MACHINE = nephos $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(NEPHOS_NPS_KERNEL) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9130_32X_PLATFORM_MODULE) \ - $(INGRASYS_S9230_64X_PLATFORM_MODULE) \ - $(ACCTON_AS7116_54X_PLATFORM_MODULE) \ - $(CIG_CS6436_56P_PLATFORM_MODULE) + $(INGRASYS_S9230_64X_PLATFORM_MODULE) \ + $(ACCTON_AS7116_54X_PLATFORM_MODULE) \ + $(PEGATRON_PORSCHE_PLATFORM_MODULE) \ + $(PEGATRON_FN_6254_DN_F_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/nephos/platform-modules-pegatron.mk b/platform/nephos/platform-modules-pegatron.mk index 9a411763cec2..ac5bd16cf9c7 100755 --- a/platform/nephos/platform-modules-pegatron.mk +++ b/platform/nephos/platform-modules-pegatron.mk @@ -1,13 +1,22 @@ # Pegatron Platform modules PEGATRON_PORSCHE_PLATFORM_MODULE_VERSION = 0.1 +PEGATRON_FN_6254_DN_F_PLATFORM_MODULE_VERSION = 0.1 export PEGATRON_PORSCHE_PLATFORM_MODULE_VERSION +export PEGATRON_FN_6254_DN_F_PLATFORM_MODULE_VERSION PEGATRON_PORSCHE_PLATFORM_MODULE = sonic-platform-pegatron-porsche_$(PEGATRON_PORSCHE_PLATFORM_MODULE_VERSION)_amd64.deb $(PEGATRON_PORSCHE_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-pegatron $(PEGATRON_PORSCHE_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(PEGATRON_PORSCHE_PLATFORM_MODULE)_PLATFORM = x86_64-pegatron_porsche-r0 SONIC_DPKG_DEBS += $(PEGATRON_PORSCHE_PLATFORM_MODULE) +SONIC_STRETCH_DEBS += $(PEGATRON_PORSCHE_PLATFORM_MODULE) + +PEGATRON_FN_6254_DN_F_PLATFORM_MODULE = sonic-platform-pegatron-fn-6254-dn-f_$(PEGATRON_FN_6254_DN_F_PLATFORM_MODULE_VERSION)_amd64.deb +$(PEGATRON_FN_6254_DN_F_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-pegatron +$(PEGATRON_FN_6254_DN_F_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(PEGATRON_FN_6254_DN_F_PLATFORM_MODULE)_PLATFORM = x86_64-pegatron_fn_6254_dn_f-r0 +SONIC_DPKG_DEBS += $(PEGATRON_FN_6254_DN_F_PLATFORM_MODULE) +SONIC_STRETCH_DEBS += $(PEGATRON_FN_6254_DN_F_PLATFORM_MODULE) -$(eval $(call add_extra_package,$(PEGATRON_PORSCHE_PLATFORM_MODULE))) diff --git a/platform/nephos/rules.mk b/platform/nephos/rules.mk index 2e2ee702fb5b..8402fac1747b 100644 --- a/platform/nephos/rules.mk +++ b/platform/nephos/rules.mk @@ -1,5 +1,6 @@ include $(PLATFORM_PATH)/sdk.mk include $(PLATFORM_PATH)/sai.mk +include $(PLATFORM_PATH)/platform-modules-pegatron.mk include $(PLATFORM_PATH)/platform-modules-ingrasys.mk include $(PLATFORM_PATH)/platform-modules-accton.mk include $(PLATFORM_PATH)/platform-modules-cig.mk diff --git a/platform/nephos/sonic-platform-modules-pegatron/common/modules/pegatron_hwmon_mcu.c b/platform/nephos/sonic-platform-modules-pegatron/common/modules/pegatron_hwmon_mcu.c index 76cbd8844708..01b64bce9019 100644 --- a/platform/nephos/sonic-platform-modules-pegatron/common/modules/pegatron_hwmon_mcu.c +++ b/platform/nephos/sonic-platform-modules-pegatron/common/modules/pegatron_hwmon_mcu.c @@ -55,13 +55,6 @@ #define SET_BIT(data, bit) data |= (1 << bit) #define CLEAR_BIT(data, bit) data &= ~(1 << bit) -enum chips -{ - mercedes3 = 0, - cadillac, - porsche, -}; - enum fan_alert { FAN_OUTER_RPM_OVER_ALERT_BIT = 0, @@ -1339,7 +1332,7 @@ static int pega_hwmon_mcu_remove(struct i2c_client *client) } static const struct i2c_device_id pega_hwmon_mcu_id[] = { - { "porsche_hwmon_mcu", porsche }, + { "pega_hwmon_mcu", 0 }, {} }; MODULE_DEVICE_TABLE(i2c, pega_hwmon_mcu_id); diff --git a/platform/nephos/sonic-platform-modules-pegatron/debian/control b/platform/nephos/sonic-platform-modules-pegatron/debian/control index 18e74be1455d..c24275f6b94e 100755 --- a/platform/nephos/sonic-platform-modules-pegatron/debian/control +++ b/platform/nephos/sonic-platform-modules-pegatron/debian/control @@ -7,6 +7,10 @@ Standards-Version: 3.9.3 Package: sonic-platform-pegatron-porsche Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-4.9.0-8-amd64 Description: kernel modules for platform devices such as fan, led, sfp +Package: sonic-platform-pegatron-fn-6254-dn-f +Architecture: amd64 +Depends: linux-image-4.9.0-8-amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-pegatron/debian/rules b/platform/nephos/sonic-platform-modules-pegatron/debian/rules index 472ec939a47c..9fbb702c47a2 100755 --- a/platform/nephos/sonic-platform-modules-pegatron/debian/rules +++ b/platform/nephos/sonic-platform-modules-pegatron/debian/rules @@ -19,7 +19,7 @@ PACKAGE_PRE_NAME := sonic-platform-pegatron KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= porsche +MODULE_DIRS:= porsche fn-6254-dn-f MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service diff --git a/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/kernel_patch/0001-update-Intel-ixgbe-driver-for-pegatron-fn-6254-dn-f.patch b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/kernel_patch/0001-update-Intel-ixgbe-driver-for-pegatron-fn-6254-dn-f.patch new file mode 100644 index 000000000000..8a81fb192e22 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/kernel_patch/0001-update-Intel-ixgbe-driver-for-pegatron-fn-6254-dn-f.patch @@ -0,0 +1,4666 @@ +From 9204bacfb0946029baa1cb57a269f2f23b5149b0 Mon Sep 17 00:00:00 2001 +From: PeterLin +Date: Tue, 30 Apr 2019 17:43:32 +0800 +Subject: [PATCH] update Intel ixgbe driver for pegatron fn-6254-dn-f + +--- + drivers/net/ethernet/intel/ixgbe/ixgbe.h | 10 + + drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c | 28 +- + drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c | 15 +- + drivers/net/ethernet/intel/ixgbe/ixgbe_common.c | 439 ++++-- + drivers/net/ethernet/intel/ixgbe/ixgbe_common.h | 7 +- + drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 103 +- + drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 85 +- + drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | 407 +++--- + drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h | 27 +- + drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 153 +- + drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c | 20 +- + drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | 1668 +++++++++++++++++----- + 12 files changed, 2282 insertions(+), 680 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h +index b06e32d..255ec3b 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h +@@ -89,6 +89,7 @@ + + /* Supported Rx Buffer Sizes */ + #define IXGBE_RXBUFFER_256 256 /* Used for skb receive header */ ++#define IXGBE_RXBUFFER_1536 1536 + #define IXGBE_RXBUFFER_2K 2048 + #define IXGBE_RXBUFFER_3K 3072 + #define IXGBE_RXBUFFER_4K 4096 +@@ -661,6 +662,9 @@ struct ixgbe_adapter { + #define IXGBE_FLAG2_PHY_INTERRUPT BIT(11) + #define IXGBE_FLAG2_UDP_TUN_REREG_NEEDED BIT(12) + #define IXGBE_FLAG2_VLAN_PROMISC BIT(13) ++#define IXGBE_FLAG2_EEE_CAPABLE BIT(14) ++#define IXGBE_FLAG2_EEE_ENABLED BIT(15) ++#define IXGBE_FLAG2_RX_LEGACY BIT(16) + + /* Tx fast path data */ + int num_tx_queues; +@@ -861,7 +865,9 @@ enum ixgbe_boards { + board_X540, + board_X550, + board_X550EM_x, ++ board_x550em_x_fw, + board_x550em_a, ++ board_x550em_a_fw, + }; + + extern const struct ixgbe_info ixgbe_82598_info; +@@ -869,7 +875,9 @@ extern const struct ixgbe_info ixgbe_82599_info; + extern const struct ixgbe_info ixgbe_X540_info; + extern const struct ixgbe_info ixgbe_X550_info; + extern const struct ixgbe_info ixgbe_X550EM_x_info; ++extern const struct ixgbe_info ixgbe_x550em_x_fw_info; + extern const struct ixgbe_info ixgbe_x550em_a_info; ++extern const struct ixgbe_info ixgbe_x550em_a_fw_info; + #ifdef CONFIG_IXGBE_DCB + extern const struct dcbnl_rtnl_ops dcbnl_ops; + #endif +@@ -1027,4 +1035,6 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, + struct ixgbe_ring *tx_ring); + u32 ixgbe_rss_indir_tbl_entries(struct ixgbe_adapter *adapter); + void ixgbe_store_reta(struct ixgbe_adapter *adapter); ++s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, ++ u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm); + #endif /* _IXGBE_H_ */ +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c +index fb51be7..8a32eb7 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c +@@ -139,8 +139,6 @@ static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) + case ixgbe_phy_tn: + phy->ops.setup_link = &ixgbe_setup_phy_link_tnx; + phy->ops.check_link = &ixgbe_check_phy_link_tnx; +- phy->ops.get_firmware_version = +- &ixgbe_get_phy_firmware_version_tnx; + break; + case ixgbe_phy_nl: + phy->ops.reset = &ixgbe_reset_phy_nl; +@@ -177,31 +175,9 @@ static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) + **/ + static s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw) + { +-#ifndef CONFIG_SPARC +- u32 regval; +- u32 i; +-#endif + s32 ret_val; + + ret_val = ixgbe_start_hw_generic(hw); +- +-#ifndef CONFIG_SPARC +- /* Disable relaxed ordering */ +- for (i = 0; ((i < hw->mac.max_tx_queues) && +- (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { +- regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i)); +- regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN; +- IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval); +- } +- +- for (i = 0; ((i < hw->mac.max_rx_queues) && +- (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { +- regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); +- regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN | +- IXGBE_DCA_RXCTRL_HEAD_WRO_EN); +- IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); +- } +-#endif + if (ret_val) + return ret_val; + +@@ -367,7 +343,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw) + } + + /* Negotiate the fc mode to use */ +- ixgbe_fc_autoneg(hw); ++ hw->mac.ops.fc_autoneg(hw); + + /* Disable any previous flow control settings */ + fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); +@@ -1179,6 +1155,7 @@ static const struct ixgbe_mac_operations mac_ops_82598 = { + .get_link_capabilities = &ixgbe_get_link_capabilities_82598, + .led_on = &ixgbe_led_on_generic, + .led_off = &ixgbe_led_off_generic, ++ .init_led_link_act = ixgbe_init_led_link_act_generic, + .blink_led_start = &ixgbe_blink_led_start_generic, + .blink_led_stop = &ixgbe_blink_led_stop_generic, + .set_rar = &ixgbe_set_rar_generic, +@@ -1193,6 +1170,7 @@ static const struct ixgbe_mac_operations mac_ops_82598 = { + .set_vfta = &ixgbe_set_vfta_82598, + .fc_enable = &ixgbe_fc_enable_82598, + .setup_fc = ixgbe_setup_fc_generic, ++ .fc_autoneg = ixgbe_fc_autoneg, + .set_fw_drv_ver = NULL, + .acquire_swfw_sync = &ixgbe_acquire_swfw_sync, + .release_swfw_sync = &ixgbe_release_swfw_sync, +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +index 63b2500..d602637 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +@@ -331,8 +331,6 @@ static s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw) + case ixgbe_phy_tn: + phy->ops.check_link = &ixgbe_check_phy_link_tnx; + phy->ops.setup_link = &ixgbe_setup_phy_link_tnx; +- phy->ops.get_firmware_version = +- &ixgbe_get_phy_firmware_version_tnx; + break; + default: + break; +@@ -1451,7 +1449,7 @@ do { \ + * @atr_input: input bitstream to compute the hash on + * @input_mask: mask for the input bitstream + * +- * This function serves two main purposes. First it applys the input_mask ++ * This function serves two main purposes. First it applies the input_mask + * to the atr_input resulting in a cleaned up atr_input data stream. + * Secondly it computes the hash and stores it in the bkt_hash field at + * the end of the input byte stream. This way it will be available for +@@ -1591,15 +1589,17 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, + + switch (ntohs(input_mask->formatted.vlan_id) & 0xEFFF) { + case 0x0000: +- /* mask VLAN ID, fall through to mask VLAN priority */ ++ /* mask VLAN ID */ + fdirm |= IXGBE_FDIRM_VLANID; ++ /* fall through */ + case 0x0FFF: + /* mask VLAN priority */ + fdirm |= IXGBE_FDIRM_VLANP; + break; + case 0xE000: +- /* mask VLAN ID only, fall through */ ++ /* mask VLAN ID only */ + fdirm |= IXGBE_FDIRM_VLANID; ++ /* fall through */ + case 0xEFFF: + /* no VLAN fields masked */ + break; +@@ -1610,8 +1610,9 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, + + switch (input_mask->formatted.flex_bytes & 0xFFFF) { + case 0x0000: +- /* Mask Flex Bytes, fall through */ ++ /* Mask Flex Bytes */ + fdirm |= IXGBE_FDIRM_FLEX; ++ /* fall through */ + case 0xFFFF: + break; + default: +@@ -2204,6 +2205,7 @@ static const struct ixgbe_mac_operations mac_ops_82599 = { + .get_link_capabilities = &ixgbe_get_link_capabilities_82599, + .led_on = &ixgbe_led_on_generic, + .led_off = &ixgbe_led_off_generic, ++ .init_led_link_act = ixgbe_init_led_link_act_generic, + .blink_led_start = &ixgbe_blink_led_start_generic, + .blink_led_stop = &ixgbe_blink_led_stop_generic, + .set_rar = &ixgbe_set_rar_generic, +@@ -2219,6 +2221,7 @@ static const struct ixgbe_mac_operations mac_ops_82599 = { + .set_vfta = &ixgbe_set_vfta_generic, + .fc_enable = &ixgbe_fc_enable_generic, + .setup_fc = ixgbe_setup_fc_generic, ++ .fc_autoneg = ixgbe_fc_autoneg, + .set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic, + .init_uta_tables = &ixgbe_init_uta_tables_generic, + .setup_sfp = &ixgbe_setup_sfp_modules_82599, +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +index ad33622..fd055cc 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +@@ -79,16 +79,28 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) + + switch (hw->phy.media_type) { + case ixgbe_media_type_fiber: +- hw->mac.ops.check_link(hw, &speed, &link_up, false); +- /* if link is down, assume supported */ +- if (link_up) +- supported = speed == IXGBE_LINK_SPEED_1GB_FULL ? ++ /* flow control autoneg black list */ ++ switch (hw->device_id) { ++ case IXGBE_DEV_ID_X550EM_A_SFP: ++ case IXGBE_DEV_ID_X550EM_A_SFP_N: ++ supported = false; ++ break; ++ default: ++ hw->mac.ops.check_link(hw, &speed, &link_up, false); ++ /* if link is down, assume supported */ ++ if (link_up) ++ supported = speed == IXGBE_LINK_SPEED_1GB_FULL ? + true : false; +- else +- supported = true; ++ else ++ supported = true; ++ } ++ + break; + case ixgbe_media_type_backplane: +- supported = true; ++ if (hw->device_id == IXGBE_DEV_ID_X550EM_X_XFI) ++ supported = false; ++ else ++ supported = true; + break; + case ixgbe_media_type_copper: + /* only some copper devices support flow control autoneg */ +@@ -100,6 +112,8 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) + case IXGBE_DEV_ID_X550T1: + case IXGBE_DEV_ID_X550EM_X_10G_T: + case IXGBE_DEV_ID_X550EM_A_10G_T: ++ case IXGBE_DEV_ID_X550EM_A_1G_T: ++ case IXGBE_DEV_ID_X550EM_A_1G_T_L: + supported = true; + break; + default: +@@ -109,6 +123,10 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) + break; + } + ++ if (!supported) ++ hw_dbg(hw, "Device %x does not support flow control autoneg\n", ++ hw->device_id); ++ + return supported; + } + +@@ -153,7 +171,7 @@ s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw) + if (ret_val) + return ret_val; + +- /* only backplane uses autoc so fall though */ ++ /* fall through - only backplane uses autoc */ + case ixgbe_media_type_fiber: + reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); + +@@ -279,6 +297,10 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) + s32 ret_val; + u32 ctrl_ext; + u16 device_caps; ++#if 1 //by hilbert ++ s32 rc; ++ u16 regVal=0; ++#endif + + /* Set the media type */ + hw->phy.media_type = hw->mac.ops.get_media_type(hw); +@@ -298,10 +320,12 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) + IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); + IXGBE_WRITE_FLUSH(hw); + +- /* Setup flow control */ +- ret_val = hw->mac.ops.setup_fc(hw); +- if (ret_val) +- return ret_val; ++ /* Setup flow control if method for doing so */ ++ if (hw->mac.ops.setup_fc) { ++ ret_val = hw->mac.ops.setup_fc(hw); ++ if (ret_val) ++ return ret_val; ++ } + + /* Cashe bit indicating need for crosstalk fix */ + switch (hw->mac.type) { +@@ -322,6 +346,67 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) + /* Clear adapter stopped flag */ + hw->adapter_stopped = false; + ++#if 1 /* To modify speed LED polarity and configure led on only for speed 1G in M88E1512 ++ * for Porsche2 platform. By hilbert ++ * From 88E1512 datasheet: ++ * Page register: 0x16 ++ * LED functon control register: 0x10 in page 3 ++ * LED polarity control register: 0x11 in page 3 ++ */ ++ ++ if (hw->mac.type == ixgbe_mac_x550em_a && ++ (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper)) { ++ /* For M88E1512, to select page 3 in register 0x16 */ ++ regVal = 0x03; ++ rc = hw->phy.ops.write_reg(hw, 0x16, MDIO_MMD_PMAPMD, regVal); ++ if (rc) { ++ hw_err(hw, "page register write failed, rc:%x\n", rc); ++ } ++#if 0 //for debug ++ /* For M88E1512, read from register 0x16 */ ++ regVal = 0x00; ++ rc = hw->phy.ops.read_reg(hw, 0x16, MDIO_MMD_PMAPMD, ®Val); ++ if (rc) { ++ hw_err(hw, "phy register read failed, rc:%x\n", rc); ++ } ++ hw_err(hw, "####read phy register 0x16 again, value:%x\n", regVal); ++#endif ++ /* For M88E1512, read from page 3, register 0x11 */ ++ regVal = 0x00; ++ rc = hw->phy.ops.read_reg(hw, 0x11, MDIO_MMD_PMAPMD, ®Val); ++ if (rc) { ++ hw_err(hw, "led polarity register read failed, rc:%x\n", rc); ++ } ++ ++ /* For M88E1512, write to page 3 register 0x11 with polarity bit set */ ++ regVal |= 0x01; ++ rc = hw->phy.ops.write_reg(hw, 0x11, MDIO_MMD_PMAPMD, regVal); ++ if (rc) { ++ hw_err(hw, "led polarity register write failed, rc:%x\n", rc); ++ } ++ ++ /* For M88E1512, read from page 3, register 16 */ ++ regVal = 0x00; ++ rc = hw->phy.ops.read_reg(hw, 0x10, MDIO_MMD_PMAPMD, ®Val); ++ if (rc) { ++ hw_err(hw, "led function control register read failed, rc:%x\n", rc); ++ } ++ ++ /* For M88E1512, write to page 3 register 16 with only 1000M led on */ ++ regVal = (regVal & 0xFFF0) | 0x0007; ++ rc = hw->phy.ops.write_reg(hw, 0x10, MDIO_MMD_PMAPMD, regVal); ++ if (rc) { ++ hw_err(hw, "led function control register write failed, rc:%x\n", rc); ++ } ++ ++ /* For M88E1512, write page 22 back to default 0 */ ++ regVal = 0x00; ++ rc = hw->phy.ops.write_reg(hw, 0x16, MDIO_MMD_PMAPMD, regVal); ++ if (rc) { ++ hw_err(hw, "page register write failed, rc:%x\n", rc); ++ } ++ } ++#endif + return 0; + } + +@@ -346,25 +431,6 @@ s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw) + } + IXGBE_WRITE_FLUSH(hw); + +-#ifndef CONFIG_SPARC +- /* Disable relaxed ordering */ +- for (i = 0; i < hw->mac.max_tx_queues; i++) { +- u32 regval; +- +- regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i)); +- regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN; +- IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval); +- } +- +- for (i = 0; i < hw->mac.max_rx_queues; i++) { +- u32 regval; +- +- regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); +- regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN | +- IXGBE_DCA_RXCTRL_HEAD_WRO_EN); +- IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); +- } +-#endif + return 0; + } + +@@ -390,6 +456,10 @@ s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw) + status = hw->mac.ops.start_hw(hw); + } + ++ /* Initialize the LED link active for LED blink support */ ++ if (hw->mac.ops.init_led_link_act) ++ hw->mac.ops.init_led_link_act(hw); ++ + return status; + } + +@@ -773,22 +843,100 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw) + } + + /** ++ * ixgbe_init_led_link_act_generic - Store the LED index link/activity. ++ * @hw: pointer to hardware structure ++ * ++ * Store the index for the link active LED. This will be used to support ++ * blinking the LED. ++ **/ ++s32 ixgbe_init_led_link_act_generic(struct ixgbe_hw *hw) ++{ ++ struct ixgbe_mac_info *mac = &hw->mac; ++ u32 led_reg, led_mode; ++ u16 i; ++ ++ led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); ++ ++ /* Get LED link active from the LEDCTL register */ ++ for (i = 0; i < 4; i++) { ++ led_mode = led_reg >> IXGBE_LED_MODE_SHIFT(i); ++ ++ if ((led_mode & IXGBE_LED_MODE_MASK_BASE) == ++ IXGBE_LED_LINK_ACTIVE) { ++ mac->led_link_act = i; ++ return 0; ++ } ++ } ++ ++ /* If LEDCTL register does not have the LED link active set, then use ++ * known MAC defaults. ++ */ ++ switch (hw->mac.type) { ++ case ixgbe_mac_x550em_a: ++ mac->led_link_act = 0; ++ break; ++ case ixgbe_mac_X550EM_x: ++ mac->led_link_act = 1; ++ break; ++ default: ++ mac->led_link_act = 2; ++ } ++ ++ return 0; ++} ++ ++/** + * ixgbe_led_on_generic - Turns on the software controllable LEDs. + * @hw: pointer to hardware structure + * @index: led number to turn on + **/ + s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index) + { +- u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); +- +- if (index > 3) +- return IXGBE_ERR_PARAM; +- +- /* To turn on the LED, set mode to ON. */ +- led_reg &= ~IXGBE_LED_MODE_MASK(index); +- led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index); +- IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); +- IXGBE_WRITE_FLUSH(hw); ++ u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); ++ s32 rc; ++ u16 regVal; ++ ++ /* following led behavior was modified by hilbert, ++ * to force led on through C22 MDI command. ++ */ ++ if (hw->mac.type == ixgbe_mac_x550em_a) { ++ /* For M88E1512, to select page 3 in register 22 */ ++ regVal = 0x03; ++ rc = hw->phy.ops.write_reg(hw, 0x16, MDIO_MMD_PMAPMD, regVal); ++ if (rc) { ++ hw_err(hw, "page register write failed, rc:%x\n", rc); ++ } ++ ++ /* For M88E1512, read from page 3, register 16 */ ++ regVal = 0x00; ++ rc = hw->phy.ops.read_reg(hw, 0x10, MDIO_MMD_PMAPMD, ®Val); ++ if (rc) { ++ hw_err(hw, "led function control register read failed, rc:%x\n", rc); ++ } ++ ++ /* For M88E1512, write to page 3 register 16 with force led on */ ++ regVal = (regVal & 0xFF00) | 0x0099; ++ rc = hw->phy.ops.write_reg(hw, 0x10, MDIO_MMD_PMAPMD, regVal); ++ if (rc) { ++ hw_err(hw, "led function control register write failed, rc:%x\n", rc); ++ } ++ ++ /* For M88E1512, write page 22 back to default 0 */ ++ regVal = 0x00; ++ rc = hw->phy.ops.write_reg(hw, 0x16, MDIO_MMD_PMAPMD, regVal); ++ if (rc) { ++ hw_err(hw, "page register write failed, rc:%x\n", rc); ++ } ++ } else { ++ if (index > 3) ++ return IXGBE_ERR_PARAM; ++ ++ /* To turn on the LED, set mode to ON. */ ++ led_reg &= ~IXGBE_LED_MODE_MASK(index); ++ led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index); ++ IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); ++ IXGBE_WRITE_FLUSH(hw); ++ } + + return 0; + } +@@ -801,15 +949,50 @@ s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index) + s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index) + { + u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); +- +- if (index > 3) +- return IXGBE_ERR_PARAM; +- +- /* To turn off the LED, set mode to OFF. */ +- led_reg &= ~IXGBE_LED_MODE_MASK(index); +- led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index); +- IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); +- IXGBE_WRITE_FLUSH(hw); ++ s32 rc; ++ u16 regVal; ++ ++ /* following led behavior was modified by hilbert, ++ * to force led on through C22 MDI command. ++ */ ++ if (hw->mac.type == ixgbe_mac_x550em_a) { ++ /* For M88E1512, to select page 3 in register 22 */ ++ regVal = 0x03; ++ rc = hw->phy.ops.write_reg(hw, 0x16, MDIO_MMD_PMAPMD, regVal); ++ if (rc) { ++ hw_err(hw, "page register write failed, rc:%x\n", rc); ++ } ++ ++ /* For M88E1512, read from page 3, register 16 */ ++ regVal = 0x00; ++ rc = hw->phy.ops.read_reg(hw, 0x10, MDIO_MMD_PMAPMD, ®Val); ++ if (rc) { ++ hw_err(hw, "led function control register read failed, rc:%x\n", rc); ++ } ++ ++ /* For M88E1512, write to page 3 register 16 with force led on */ ++ regVal = (regVal & 0xFF00) | 0x0088; ++ rc = hw->phy.ops.write_reg(hw, 0x10, MDIO_MMD_PMAPMD, regVal); ++ if (rc) { ++ hw_err(hw, "led function control register write failed, rc:%x\n", rc); ++ } ++ ++ /* For M88E1512, write page 22 back to default 0 */ ++ regVal = 0x00; ++ rc = hw->phy.ops.write_reg(hw, 0x16, MDIO_MMD_PMAPMD, regVal); ++ if (rc) { ++ hw_err(hw, "page register write failed, rc:%x\n", rc); ++ } ++ } else { ++ if (index > 3) ++ return IXGBE_ERR_PARAM; ++ ++ /* To turn off the LED, set mode to OFF. */ ++ led_reg &= ~IXGBE_LED_MODE_MASK(index); ++ led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index); ++ IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); ++ IXGBE_WRITE_FLUSH(hw); ++ } + + return 0; + } +@@ -2127,7 +2310,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw) + } + + /* Negotiate the fc mode to use */ +- ixgbe_fc_autoneg(hw); ++ hw->mac.ops.fc_autoneg(hw); + + /* Disable any previous flow control settings */ + mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); +@@ -2231,8 +2414,8 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw) + * Find the intersection between advertised settings and link partner's + * advertised settings + **/ +-static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, +- u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) ++s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, ++ u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) + { + if ((!(adv_reg)) || (!(lp_reg))) + return IXGBE_ERR_FC_NOT_NEGOTIATED; +@@ -3334,6 +3517,13 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + else + *speed = IXGBE_LINK_SPEED_100_FULL; + break; ++ case IXGBE_LINKS_SPEED_10_X550EM_A: ++ *speed = IXGBE_LINK_SPEED_UNKNOWN; ++ if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T || ++ hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) { ++ *speed = IXGBE_LINK_SPEED_10_FULL; ++ } ++ break; + default: + *speed = IXGBE_LINK_SPEED_UNKNOWN; + } +@@ -3491,7 +3681,7 @@ void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, + rxpktsize <<= IXGBE_RXPBSIZE_SHIFT; + for (; i < (num_pb / 2); i++) + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); +- /* Fall through to configure remaining packet buffers */ ++ /* fall through - configure remaining packet buffers */ + case (PBA_STRATEGY_EQUAL): + /* Divide the remaining Rx packet buffer evenly among the TCs */ + rxpktsize = (pbsize / (num_pb - i)) << IXGBE_RXPBSIZE_SHIFT; +@@ -3530,7 +3720,7 @@ void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, + * Calculates the checksum for some buffer on a specified length. The + * checksum calculated is returned. + **/ +-static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) ++u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) + { + u32 i; + u8 sum = 0; +@@ -3545,43 +3735,29 @@ static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) + } + + /** +- * ixgbe_host_interface_command - Issue command to manageability block ++ * ixgbe_hic_unlocked - Issue command to manageability block unlocked + * @hw: pointer to the HW structure +- * @buffer: contains the command to write and where the return status will +- * be placed ++ * @buffer: command to write and where the return status will be placed + * @length: length of buffer, must be multiple of 4 bytes + * @timeout: time in ms to wait for command completion +- * @return_data: read and return data from the buffer (true) or not (false) +- * Needed because FW structures are big endian and decoding of +- * these fields can be 8 bit or 16 bit based on command. Decoding +- * is not easily understood without making a table of commands. +- * So we will leave this up to the caller to read back the data +- * in these cases. + * +- * Communicates with the manageability block. On success return 0 +- * else return IXGBE_ERR_HOST_INTERFACE_COMMAND. ++ * Communicates with the manageability block. On success return 0 ++ * else returns semaphore error when encountering an error acquiring ++ * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. ++ * ++ * This function assumes that the IXGBE_GSSR_SW_MNG_SM semaphore is held ++ * by the caller. + **/ +-s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer, +- u32 length, u32 timeout, +- bool return_data) ++s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 length, ++ u32 timeout) + { +- u32 hdr_size = sizeof(struct ixgbe_hic_hdr); +- u32 hicr, i, bi, fwsts; +- u16 buf_len, dword_len; +- union { +- struct ixgbe_hic_hdr hdr; +- u32 u32arr[1]; +- } *bp = buffer; +- s32 status; ++ u32 hicr, i, fwsts; ++ u16 dword_len; + + if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { + hw_dbg(hw, "Buffer length failure buffersize-%d.\n", length); + return IXGBE_ERR_HOST_INTERFACE_COMMAND; + } +- /* Take management host interface semaphore */ +- status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); +- if (status) +- return status; + + /* Set bit 9 of FWSTS clearing FW reset indication */ + fwsts = IXGBE_READ_REG(hw, IXGBE_FWSTS); +@@ -3591,15 +3767,13 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer, + hicr = IXGBE_READ_REG(hw, IXGBE_HICR); + if (!(hicr & IXGBE_HICR_EN)) { + hw_dbg(hw, "IXGBE_HOST_EN bit disabled.\n"); +- status = IXGBE_ERR_HOST_INTERFACE_COMMAND; +- goto rel_out; ++ return IXGBE_ERR_HOST_INTERFACE_COMMAND; + } + + /* Calculate length in DWORDs. We must be DWORD aligned */ + if (length % sizeof(u32)) { + hw_dbg(hw, "Buffer length failure, not aligned to dword"); +- status = IXGBE_ERR_INVALID_ARGUMENT; +- goto rel_out; ++ return IXGBE_ERR_INVALID_ARGUMENT; + } + + dword_len = length >> 2; +@@ -3609,7 +3783,7 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer, + */ + for (i = 0; i < dword_len; i++) + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_FLEX_MNG, +- i, cpu_to_le32(bp->u32arr[i])); ++ i, cpu_to_le32(buffer[i])); + + /* Setting this bit tells the ARC that a new command is pending. */ + IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C); +@@ -3623,11 +3797,54 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer, + + /* Check command successful completion. */ + if ((timeout && i == timeout) || +- !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) { +- hw_dbg(hw, "Command has failed with no status valid.\n"); +- status = IXGBE_ERR_HOST_INTERFACE_COMMAND; +- goto rel_out; ++ !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) ++ return IXGBE_ERR_HOST_INTERFACE_COMMAND; ++ ++ return 0; ++} ++ ++/** ++ * ixgbe_host_interface_command - Issue command to manageability block ++ * @hw: pointer to the HW structure ++ * @buffer: contains the command to write and where the return status will ++ * be placed ++ * @length: length of buffer, must be multiple of 4 bytes ++ * @timeout: time in ms to wait for command completion ++ * @return_data: read and return data from the buffer (true) or not (false) ++ * Needed because FW structures are big endian and decoding of ++ * these fields can be 8 bit or 16 bit based on command. Decoding ++ * is not easily understood without making a table of commands. ++ * So we will leave this up to the caller to read back the data ++ * in these cases. ++ * ++ * Communicates with the manageability block. On success return 0 ++ * else return IXGBE_ERR_HOST_INTERFACE_COMMAND. ++ **/ ++s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer, ++ u32 length, u32 timeout, ++ bool return_data) ++{ ++ u32 hdr_size = sizeof(struct ixgbe_hic_hdr); ++ union { ++ struct ixgbe_hic_hdr hdr; ++ u32 u32arr[1]; ++ } *bp = buffer; ++ u16 buf_len, dword_len; ++ s32 status; ++ u32 bi; ++ ++ if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { ++ hw_dbg(hw, "Buffer length failure buffersize-%d.\n", length); ++ return IXGBE_ERR_HOST_INTERFACE_COMMAND; + } ++ /* Take management host interface semaphore */ ++ status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); ++ if (status) ++ return status; ++ ++ status = ixgbe_hic_unlocked(hw, buffer, length, timeout); ++ if (status) ++ goto rel_out; + + if (!return_data) + goto rel_out; +@@ -3674,6 +3891,8 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer, + * @min: driver version minor number + * @build: driver version build number + * @sub: driver version sub build number ++ * @len: length of driver_ver string ++ * @driver_ver: driver string + * + * Sends driver version number to firmware through the manageability + * block. On success return 0 +@@ -3681,7 +3900,8 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer, + * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + **/ + s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, +- u8 build, u8 sub) ++ u8 build, u8 sub, __always_unused u16 len, ++ __always_unused const char *driver_ver) + { + struct ixgbe_hic_drv_info fw_cmd; + int i; +@@ -4033,15 +4253,6 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, + speedcnt++; + highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL; + +- /* If we already have link at this speed, just jump out */ +- status = hw->mac.ops.check_link(hw, &link_speed, &link_up, +- false); +- if (status) +- return status; +- +- if (link_speed == IXGBE_LINK_SPEED_10GB_FULL && link_up) +- goto out; +- + /* Set the module link speed */ + switch (hw->phy.media_type) { + case ixgbe_media_type_fiber: +@@ -4093,15 +4304,6 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, + if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN) + highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL; + +- /* If we already have link at this speed, just jump out */ +- status = hw->mac.ops.check_link(hw, &link_speed, &link_up, +- false); +- if (status) +- return status; +- +- if (link_speed == IXGBE_LINK_SPEED_1GB_FULL && link_up) +- goto out; +- + /* Set the module link speed */ + switch (hw->phy.media_type) { + case ixgbe_media_type_fiber: +@@ -4208,4 +4410,23 @@ void ixgbe_set_soft_rate_select_speed(struct ixgbe_hw *hw, + hw_dbg(hw, "Failed to write Rx Rate Select RS0\n"); + return; + } ++ ++ /* Set RS1 */ ++ status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB, ++ IXGBE_I2C_EEPROM_DEV_ADDR2, ++ &eeprom_data); ++ if (status) { ++ hw_dbg(hw, "Failed to read Rx Rate Select RS1\n"); ++ return; ++ } ++ ++ eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) | rs; ++ ++ status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB, ++ IXGBE_I2C_EEPROM_DEV_ADDR2, ++ eeprom_data); ++ if (status) { ++ hw_dbg(hw, "Failed to write Rx Rate Select RS1\n"); ++ return; ++ } + } +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h +index 6d4c260..e083732 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h +@@ -49,6 +49,7 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw); + + s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index); + s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index); ++s32 ixgbe_init_led_link_act_generic(struct ixgbe_hw *hw); + + s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw); + s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data); +@@ -110,9 +111,13 @@ void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf); + void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf); + s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps); + s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, +- u8 build, u8 ver); ++ u8 build, u8 ver, u16 len, const char *str); ++u8 ixgbe_calculate_checksum(u8 *buffer, u32 length); + s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *, u32 length, + u32 timeout, bool return_data); ++s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 len, u32 timeout); ++s32 ixgbe_fw_phy_activity(struct ixgbe_hw *hw, u16 activity, ++ u32 (*data)[FW_PHY_ACT_DATA_COUNT]); + void ixgbe_clear_tx_pending(struct ixgbe_hw *hw); + bool ixgbe_mng_present(struct ixgbe_hw *hw); + bool ixgbe_mng_enabled(struct ixgbe_hw *hw); +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +index a137e06..6b23b74 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +@@ -172,6 +172,7 @@ static u32 ixgbe_get_supported_10gtypes(struct ixgbe_hw *hw) + case IXGBE_DEV_ID_82598_BX: + case IXGBE_DEV_ID_82599_KR: + case IXGBE_DEV_ID_X550EM_X_KR: ++ case IXGBE_DEV_ID_X550EM_X_XFI: + return SUPPORTED_10000baseKR_Full; + default: + return SUPPORTED_10000baseKX4_Full | +@@ -237,6 +238,7 @@ static int ixgbe_get_settings(struct net_device *netdev, + case ixgbe_phy_tn: + case ixgbe_phy_aq: + case ixgbe_phy_x550em_ext_t: ++ case ixgbe_phy_fw: + case ixgbe_phy_cu_unknown: + ecmd->supported |= SUPPORTED_TP; + ecmd->advertising |= ADVERTISED_TP; +@@ -394,6 +396,9 @@ static int ixgbe_set_settings(struct net_device *netdev, + if (ecmd->advertising & ADVERTISED_100baseT_Full) + advertised |= IXGBE_LINK_SPEED_100_FULL; + ++ if (ecmd->advertising & ADVERTISED_10baseT_Full) ++ advertised |= IXGBE_LINK_SPEED_10_FULL; ++ + if (old == advertised) + return err; + /* this sets the link speed and restarts auto-neg */ +@@ -491,6 +496,59 @@ static void ixgbe_set_msglevel(struct net_device *netdev, u32 data) + { + struct ixgbe_adapter *adapter = netdev_priv(netdev); + adapter->msg_enable = data; ++ ++ /* 2018/11/14 pega-julia modified start */ ++ /* Purpose : Add for light OOB LED static. */ ++ ++ struct ixgbe_hw *hw = &adapter->hw; ++ u16 regVal; ++ s32 rc; ++ ++ /* For M88E1512, write 3 in (page 0,register 22)[Page Address Register] to goto page 3 */ ++ regVal = 0x03; ++ rc = hw->phy.ops.write_reg(hw, 0x16, MDIO_MMD_PMAPMD, regVal); ++ if (rc) ++ hw_err(hw, "page register write failed, rc:%x\n", rc); ++ ++ /* For M88E1512, read from (page 3, register 16)[LED Function Control Register] */ ++ regVal = 0x00; ++ rc = hw->phy.ops.read_reg(hw, 0x10, MDIO_MMD_PMAPMD, ®Val); ++ /*hw_err(hw, "[Pega Debug] : current register value = 0x%x\n", regVal);*/ ++ if (rc) ++ hw_err(hw, "led function control register read failed, rc:%x\n", rc); ++ ++ if (data == 0) /* Turn off OOB LED. */ ++ { ++ /* For M88E1512, write to (page 3, register 16) with force led off */ ++ regVal = (regVal & 0xFF00) | 0x0088; ++ rc = hw->phy.ops.write_reg(hw, 0x10, MDIO_MMD_PMAPMD, regVal); ++ if (rc) ++ hw_err(hw, "led function control register write failed, rc:%x\n", rc); ++ } ++ else if (data == 1) /* Turn on OOB LED. */ ++ { ++ /* For M88E1512, write to (page 3, register 16) with force led on */ ++ regVal = (regVal & 0xFF00) | 0x0099; ++ rc = hw->phy.ops.write_reg(hw, 0x10, MDIO_MMD_PMAPMD, regVal); ++ if (rc) ++ hw_err(hw, "led function control register write failed, rc:%x\n", rc); ++ } ++ else /* Switch OOB LED back to normal. */ ++ { ++ /* For M88E1512, set led back to nornmal in (page 3, register 16). */ ++ regVal = (regVal & 0xFF00) | 0x0017; ++ rc = hw->phy.ops.write_reg(hw, 0x10, MDIO_MMD_PMAPMD, regVal); ++ if (rc) ++ hw_err(hw, "led function control register write failed, rc:%x\n", rc); ++ } ++ ++ /* For M88E1512, write 0 in (page 0, register 22) to back to page 0 */ ++ regVal = 0x00; ++ rc = hw->phy.ops.write_reg(hw, 0x16, MDIO_MMD_PMAPMD, regVal); ++ if (rc) ++ hw_err(hw, "page register write failed, rc:%x\n", rc); ++ ++ /* 2018/11/14 pega-julia modified end */ + } + + static int ixgbe_get_regs_len(struct net_device *netdev) +@@ -2219,22 +2277,61 @@ static int ixgbe_set_phys_id(struct net_device *netdev, + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + ++ /* Modified by hilbert for C22 MDI directly access */ ++ s32 rc; ++ u16 regVal; ++ /* Modified by hilbert done */ ++ ++ if (!hw->mac.ops.led_on || !hw->mac.ops.led_off) ++ return -EOPNOTSUPP; ++ + switch (state) { + case ETHTOOL_ID_ACTIVE: + adapter->led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + return 2; + + case ETHTOOL_ID_ON: +- hw->mac.ops.led_on(hw, hw->bus.func); ++ hw->mac.ops.led_on(hw, hw->mac.led_link_act); + break; + + case ETHTOOL_ID_OFF: +- hw->mac.ops.led_off(hw, hw->bus.func); ++ hw->mac.ops.led_off(hw, hw->mac.led_link_act); + break; + + case ETHTOOL_ID_INACTIVE: + /* Restore LED settings */ +- IXGBE_WRITE_REG(&adapter->hw, IXGBE_LEDCTL, adapter->led_reg); ++ /* Modified by hilbert for C22 MDI directly access */ ++ if (hw->mac.type == ixgbe_mac_x550em_a) { ++ /* For M88E1512, to select page 3 in register 22 */ ++ regVal = 0x03; ++ rc = hw->phy.ops.write_reg(hw, 0x16, MDIO_MMD_PMAPMD, regVal); ++ if (rc) { ++ hw_err(hw, "page register write failed, rc:%x\n", rc); ++ } ++ ++ /* For M88E1512, read from page 3, register 16 */ ++ regVal = 0x00; ++ rc = hw->phy.ops.read_reg(hw, 0x10, MDIO_MMD_PMAPMD, ®Val); ++ if (rc) { ++ hw_err(hw, "led function control register read failed, rc:%x\n", rc); ++ } ++ ++ /* For M88E1512, write to page 3 register 16 with force led on */ ++ regVal = (regVal & 0xFF00) | 0x0017; ++ rc = hw->phy.ops.write_reg(hw, 0x10, MDIO_MMD_PMAPMD, regVal); ++ if (rc) { ++ hw_err(hw, "led function control register write failed, rc:%x\n", rc); ++ } ++ ++ /* For M88E1512, write page 22 back to default 0 */ ++ regVal = 0x00; ++ rc = hw->phy.ops.write_reg(hw, 0x16, MDIO_MMD_PMAPMD, regVal); ++ if (rc) { ++ hw_err(hw, "page register write failed, rc:%x\n", rc); ++ } ++ } else { ++ IXGBE_WRITE_REG(&adapter->hw, IXGBE_LEDCTL, adapter->led_reg); ++ } + break; + } + +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +index a5428b6..a969d70 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +@@ -84,7 +84,9 @@ static const struct ixgbe_info *ixgbe_info_tbl[] = { + [board_X540] = &ixgbe_X540_info, + [board_X550] = &ixgbe_X550_info, + [board_X550EM_x] = &ixgbe_X550EM_x_info, ++ [board_x550em_x_fw] = &ixgbe_x550em_x_fw_info, + [board_x550em_a] = &ixgbe_x550em_a_info, ++ [board_x550em_a_fw] = &ixgbe_x550em_a_fw_info, + }; + + /* ixgbe_pci_tbl - PCI Device ID Table +@@ -129,9 +131,11 @@ static const struct pci_device_id ixgbe_pci_tbl[] = { + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550T), board_X550}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550T1), board_X550}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_KX4), board_X550EM_x}, ++ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_XFI), board_X550EM_x}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_KR), board_X550EM_x}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_10G_T), board_X550EM_x}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_SFP), board_X550EM_x}, ++ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_1G_T), board_x550em_x_fw}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_KR), board_x550em_a }, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_KR_L), board_x550em_a }, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_SFP_N), board_x550em_a }, +@@ -139,6 +143,8 @@ static const struct pci_device_id ixgbe_pci_tbl[] = { + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_SGMII_L), board_x550em_a }, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_10G_T), board_x550em_a}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_SFP), board_x550em_a }, ++ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_1G_T), board_x550em_a_fw }, ++ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_1G_T_L), board_x550em_a_fw }, + /* required last entry */ + {0, } + }; +@@ -179,6 +185,7 @@ MODULE_VERSION(DRV_VERSION); + static struct workqueue_struct *ixgbe_wq; + + static bool ixgbe_check_cfg_remove(struct ixgbe_hw *hw, struct pci_dev *pdev); ++static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter *); + + static int ixgbe_read_pci_cfg_word_parent(struct ixgbe_adapter *adapter, + u32 reg, u16 *value) +@@ -374,7 +381,7 @@ u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg) + if (ixgbe_removed(reg_addr)) + return IXGBE_FAILED_READ_REG; + if (unlikely(hw->phy.nw_mng_if_sel & +- IXGBE_NW_MNG_IF_SEL_ENABLE_10_100M)) { ++ IXGBE_NW_MNG_IF_SEL_SGMII_ENABLE)) { + struct ixgbe_adapter *adapter; + int i; + +@@ -2446,6 +2453,7 @@ static void ixgbe_check_overtemp_subtask(struct ixgbe_adapter *adapter) + { + struct ixgbe_hw *hw = &adapter->hw; + u32 eicr = adapter->interrupt_event; ++ s32 rc; + + if (test_bit(__IXGBE_DOWN, &adapter->state)) + return; +@@ -2484,6 +2492,12 @@ static void ixgbe_check_overtemp_subtask(struct ixgbe_adapter *adapter) + return; + + break; ++ case IXGBE_DEV_ID_X550EM_A_1G_T: ++ case IXGBE_DEV_ID_X550EM_A_1G_T_L: ++ rc = hw->phy.ops.check_overtemp(hw); ++ if (rc != IXGBE_ERR_OVERTEMP) ++ return; ++ break; + default: + if (adapter->hw.mac.type >= ixgbe_mac_X540) + return; +@@ -2530,6 +2544,18 @@ static void ixgbe_check_overtemp_event(struct ixgbe_adapter *adapter, u32 eicr) + return; + } + return; ++ case ixgbe_mac_x550em_a: ++ if (eicr & IXGBE_EICR_GPI_SDP0_X550EM_a) { ++ adapter->interrupt_event = eicr; ++ adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_EVENT; ++ ixgbe_service_event_schedule(adapter); ++ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ++ IXGBE_EICR_GPI_SDP0_X550EM_a); ++ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICR, ++ IXGBE_EICR_GPI_SDP0_X550EM_a); ++ } ++ return; ++ case ixgbe_mac_X550: + case ixgbe_mac_X540: + if (!(eicr & IXGBE_EICR_TS)) + return; +@@ -5035,7 +5061,7 @@ static void ixgbe_configure_dfwd(struct ixgbe_adapter *adapter) + static void ixgbe_configure(struct ixgbe_adapter *adapter) + { + struct ixgbe_hw *hw = &adapter->hw; +- ++ + ixgbe_configure_pb(adapter); + #ifdef CONFIG_IXGBE_DCB + ixgbe_configure_dcb(adapter); +@@ -5045,10 +5071,9 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) + * the VLVF registers will not be populated + */ + ixgbe_configure_virtualization(adapter); +- + ixgbe_set_rx_mode(adapter->netdev); + ixgbe_restore_vlan(adapter); +- ++ + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: +@@ -5075,7 +5100,6 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) + default: + break; + } +- + #ifdef CONFIG_IXGBE_DCA + /* configure DCA */ + if (adapter->flags & IXGBE_FLAG_DCA_CAPABLE) +@@ -5291,6 +5315,8 @@ void ixgbe_reinit_locked(struct ixgbe_adapter *adapter) + + while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) + usleep_range(1000, 2000); ++ if (adapter->hw.phy.type == ixgbe_phy_fw) ++ ixgbe_watchdog_link_is_down(adapter); + ixgbe_down(adapter); + /* + * If SR-IOV enabled then wait a bit before bringing the adapter +@@ -5706,6 +5732,14 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter) + break; + case ixgbe_mac_x550em_a: + adapter->flags |= IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE; ++ switch (hw->device_id) { ++ case IXGBE_DEV_ID_X550EM_A_1G_T: ++ case IXGBE_DEV_ID_X550EM_A_1G_T_L: ++ adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE; ++ break; ++ default: ++ break; ++ } + /* fall through */ + case ixgbe_mac_X550EM_x: + #ifdef CONFIG_IXGBE_DCB +@@ -5719,6 +5753,8 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter) + #endif /* IXGBE_FCOE */ + /* Fall Through */ + case ixgbe_mac_X550: ++ if (hw->mac.type == ixgbe_mac_X550) ++ adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE; + #ifdef CONFIG_IXGBE_DCA + adapter->flags &= ~IXGBE_FLAG_DCA_CAPABLE; + #endif +@@ -6093,29 +6129,28 @@ int ixgbe_open(struct net_device *netdev) + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + int err, queues; +- ++ + /* disallow open during test */ + if (test_bit(__IXGBE_TESTING, &adapter->state)) + return -EBUSY; +- ++ + netif_carrier_off(netdev); +- ++ + /* allocate transmit descriptors */ + err = ixgbe_setup_all_tx_resources(adapter); + if (err) + goto err_setup_tx; +- ++ + /* allocate receive descriptors */ + err = ixgbe_setup_all_rx_resources(adapter); + if (err) + goto err_setup_rx; +- ++ + ixgbe_configure(adapter); +- + err = ixgbe_request_irq(adapter); + if (err) + goto err_req_irq; +- ++ + /* Notify the stack of the actual queue counts. */ + if (adapter->num_rx_pools > 1) + queues = adapter->num_rx_queues_per_pool; +@@ -6791,6 +6826,9 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter) + case IXGBE_LINK_SPEED_100_FULL: + speed_str = "100 Mbps"; + break; ++ case IXGBE_LINK_SPEED_10_FULL: ++ speed_str = "10 Mbps"; ++ break; + default: + speed_str = "unknown speed"; + break; +@@ -8013,6 +8051,10 @@ static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd) + return ixgbe_ptp_set_ts_config(adapter, req); + case SIOCGHWTSTAMP: + return ixgbe_ptp_get_ts_config(adapter, req); ++ case SIOCGMIIPHY: ++ if (!adapter->hw.phy.ops.read_reg) ++ return -EOPNOTSUPP; ++ /* fall through */ + default: + return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd); + } +@@ -9480,6 +9522,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + hw->mac.ops = *ii->mac_ops; + hw->mac.type = ii->mac; + hw->mvals = ii->mvals; ++ if (ii->link_ops) ++ hw->link.ops = *ii->link_ops; + + /* EEPROM */ + hw->eeprom.ops = *ii->eeprom_ops; +@@ -9747,7 +9791,17 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + "representative who provided you with this " + "hardware.\n"); + } +- strcpy(netdev->name, "eth%d"); ++ ++ /*2019/04/11, change OOB from eth2 to eth0, for pegatron fn-6524-dn-f, Peter5_Lin*/ ++ if(!strcmp("0000:03:00.0", pci_name(pdev))) ++ strcpy(netdev->name, "eth0"); ++ else if(!strcmp("0000:03:00.1", pci_name(pdev))) ++ strcpy(netdev->name, "eth1"); ++ else if(!strcmp("0000:02:00.0", pci_name(pdev))) ++ strcpy(netdev->name, "eth2"); ++ else if(!strcmp("0000:02:00.1", pci_name(pdev))) ++ strcpy(netdev->name, "eth3"); ++ + err = register_netdev(netdev); + if (err) + goto err_register; +@@ -9777,8 +9831,9 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + * since os does not support feature + */ + if (hw->mac.ops.set_fw_drv_ver) +- hw->mac.ops.set_fw_drv_ver(hw, 0xFF, 0xFF, 0xFF, +- 0xFF); ++ hw->mac.ops.set_fw_drv_ver(hw, 0xFF, 0xFF, 0xFF, 0xFF, ++ sizeof(ixgbe_driver_version) - 1, ++ ixgbe_driver_version); + + /* add san mac addr to netdev */ + ixgbe_add_sanmac_netdev(netdev); +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +index b17464e..d914b40 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +@@ -109,8 +109,8 @@ static u8 ixgbe_ones_comp_byte_add(u8 add1, u8 add2) + * + * Returns an error code on error. + */ +-static s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, +- u16 reg, u16 *val, bool lock) ++s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, ++ u16 reg, u16 *val, bool lock) + { + u32 swfw_mask = hw->phy.phy_semaphore_mask; + int max_retry = 3; +@@ -178,36 +178,6 @@ static s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, + } + + /** +- * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation +- * @hw: pointer to the hardware structure +- * @addr: I2C bus address to read from +- * @reg: I2C device register to read from +- * @val: pointer to location to receive read value +- * +- * Returns an error code on error. +- */ +-s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr, +- u16 reg, u16 *val) +-{ +- return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, true); +-} +- +-/** +- * ixgbe_read_i2c_combined_generic_unlocked - Unlocked I2C read combined +- * @hw: pointer to the hardware structure +- * @addr: I2C bus address to read from +- * @reg: I2C device register to read from +- * @val: pointer to location to receive read value +- * +- * Returns an error code on error. +- */ +-s32 ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr, +- u16 reg, u16 *val) +-{ +- return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, false); +-} +- +-/** + * ixgbe_write_i2c_combined_generic_int - Perform I2C write combined operation + * @hw: pointer to the hardware structure + * @addr: I2C bus address to write to +@@ -217,8 +187,8 @@ s32 ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr, + * + * Returns an error code on error. + */ +-static s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, +- u16 reg, u16 val, bool lock) ++s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, ++ u16 reg, u16 val, bool lock) + { + u32 swfw_mask = hw->phy.phy_semaphore_mask; + int max_retry = 1; +@@ -273,33 +243,41 @@ static s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, + } + + /** +- * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation +- * @hw: pointer to the hardware structure +- * @addr: I2C bus address to write to +- * @reg: I2C device register to write to +- * @val: value to write ++ * ixgbe_probe_phy - Probe a single address for a PHY ++ * @hw: pointer to hardware structure ++ * @phy_addr: PHY address to probe + * +- * Returns an error code on error. +- */ +-s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw, +- u8 addr, u16 reg, u16 val) ++ * Returns true if PHY found ++ **/ ++static bool ixgbe_probe_phy(struct ixgbe_hw *hw, u16 phy_addr) + { +- return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, true); +-} ++ u16 ext_ability = 0; + +-/** +- * ixgbe_write_i2c_combined_generic_unlocked - Unlocked I2C write combined +- * @hw: pointer to the hardware structure +- * @addr: I2C bus address to write to +- * @reg: I2C device register to write to +- * @val: value to write +- * +- * Returns an error code on error. +- */ +-s32 ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, +- u8 addr, u16 reg, u16 val) +-{ +- return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, false); ++ hw->phy.mdio.prtad = phy_addr; ++ if (mdio45_probe(&hw->phy.mdio, phy_addr) != 0) { ++ return false; ++ } ++ ++ if (ixgbe_get_phy_id(hw)) { ++ return false; ++ } ++ ++ hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id); ++ ++ if (hw->phy.type == ixgbe_phy_unknown) { ++ hw->phy.ops.read_reg(hw, ++ MDIO_PMA_EXTABLE, ++ MDIO_MMD_PMAPMD, ++ &ext_ability); ++ if (ext_ability & ++ (MDIO_PMA_EXTABLE_10GBT | ++ MDIO_PMA_EXTABLE_1000BT)) ++ hw->phy.type = ixgbe_phy_cu_unknown; ++ else ++ hw->phy.type = ixgbe_phy_generic; ++ } ++ ++ return true; + } + + /** +@@ -311,7 +289,7 @@ s32 ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, + s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) + { + u32 phy_addr; +- u16 ext_ability = 0; ++ u32 status = IXGBE_ERR_PHY_ADDR_INVALID; + + if (!hw->phy.phy_semaphore_mask) { + if (hw->bus.lan_id) +@@ -320,37 +298,34 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) + hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM; + } + +- if (hw->phy.type == ixgbe_phy_unknown) { +- for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { +- hw->phy.mdio.prtad = phy_addr; +- if (mdio45_probe(&hw->phy.mdio, phy_addr) == 0) { +- ixgbe_get_phy_id(hw); +- hw->phy.type = +- ixgbe_get_phy_type_from_id(hw->phy.id); +- +- if (hw->phy.type == ixgbe_phy_unknown) { +- hw->phy.ops.read_reg(hw, +- MDIO_PMA_EXTABLE, +- MDIO_MMD_PMAPMD, +- &ext_ability); +- if (ext_ability & +- (MDIO_PMA_EXTABLE_10GBT | +- MDIO_PMA_EXTABLE_1000BT)) +- hw->phy.type = +- ixgbe_phy_cu_unknown; +- else +- hw->phy.type = +- ixgbe_phy_generic; +- } ++ if (hw->phy.type != ixgbe_phy_unknown) ++ return 0; + +- return 0; +- } ++ if (hw->phy.nw_mng_if_sel) { ++ phy_addr = (hw->phy.nw_mng_if_sel & ++ IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >> ++ IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT; ++ if (ixgbe_probe_phy(hw, phy_addr)) ++ return 0; ++ else ++ return IXGBE_ERR_PHY_ADDR_INVALID; ++ } ++ ++ for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { ++ if (ixgbe_probe_phy(hw, phy_addr)) { ++ status = 0; ++ break; + } +- /* indicate no PHY found */ +- hw->phy.mdio.prtad = MDIO_PRTAD_NONE; +- return IXGBE_ERR_PHY_ADDR_INVALID; + } +- return 0; ++ ++ /* Certain media types do not have a phy so an address will not ++ * be found and the code will take this path. Caller has to ++ * decide if it is an error or not. ++ */ ++ if (status) ++ hw->phy.mdio.prtad = MDIO_PRTAD_NONE; ++ ++ return status; + } + + /** +@@ -416,7 +391,8 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) + case TN1010_PHY_ID: + phy_type = ixgbe_phy_tn; + break; +- case X550_PHY_ID: ++ case X550_PHY_ID2: ++ case X550_PHY_ID3: + case X540_PHY_ID: + phy_type = ixgbe_phy_aq; + break; +@@ -427,6 +403,7 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) + phy_type = ixgbe_phy_nl; + break; + case X557_PHY_ID: ++ case X557_PHY_ID2: + phy_type = ixgbe_phy_x550em_ext_t; + break; + default: +@@ -477,11 +454,27 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) + */ + for (i = 0; i < 30; i++) { + msleep(100); +- hw->phy.ops.read_reg(hw, MDIO_CTRL1, +- MDIO_MMD_PHYXS, &ctrl); +- if (!(ctrl & MDIO_CTRL1_RESET)) { +- udelay(2); +- break; ++ if (hw->phy.type == ixgbe_phy_x550em_ext_t) { ++ status = hw->phy.ops.read_reg(hw, ++ IXGBE_MDIO_TX_VENDOR_ALARMS_3, ++ MDIO_MMD_PMAPMD, &ctrl); ++ if (status) ++ return status; ++ ++ if (ctrl & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) { ++ udelay(2); ++ break; ++ } ++ } else { ++ status = hw->phy.ops.read_reg(hw, MDIO_CTRL1, ++ MDIO_MMD_PHYXS, &ctrl); ++ if (status) ++ return status; ++ ++ if (!(ctrl & MDIO_CTRL1_RESET)) { ++ udelay(2); ++ break; ++ } + } + } + +@@ -494,6 +487,98 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) + } + + /** ++ * ixgbe_read_phy_mdio - Reads a value from a specified PHY register without ++ * the SWFW lock. This Clasue 22 API is patched by Hilbert ++ * @hw: pointer to hardware structure ++ * @reg_addr: 32 bit address of PHY register to read ++ * @phy_data: Pointer to read data from PHY register ++ **/ ++s32 ixgbe_read_phy_reg_mdio(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, ++ u16 *phy_data) ++{ ++ u32 i, data, command; ++ ++ /* Setup and write the read command */ ++ command = (reg_addr << IXGBE_MSCA_DEV_TYPE_SHIFT) | ++ (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) | ++ IXGBE_MSCA_OLD_PROTOCOL | IXGBE_MSCA_READ_AUTOINC | ++ IXGBE_MSCA_MDI_COMMAND; ++ ++ IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); ++ ++ /* Check every 10 usec to see if the address cycle completed. ++ * The MDI Command bit will clear when the operation is ++ * complete ++ */ ++ for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { ++ udelay(10); ++ ++ command = IXGBE_READ_REG(hw, IXGBE_MSCA); ++ if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) ++ break; ++ } ++ ++ ++ if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { ++ hw_dbg(hw, "PHY address command did not complete.\n"); ++ return IXGBE_ERR_PHY; ++ } ++ ++ /* Read operation is complete. Get the data ++ * from MSRWD ++ */ ++ data = IXGBE_READ_REG(hw, IXGBE_MSRWD); ++ data >>= IXGBE_MSRWD_READ_DATA_SHIFT; ++ *phy_data = (u16)(data); ++ ++ return 0; ++} ++ ++/** ++ * ixgbe_write_phy_reg_mdio - Writes a value to specified PHY register ++ * without SWFW lock. This Clause 22 API is patched by Hilbert ++ * @hw: pointer to hardware structure ++ * @reg_addr: 32 bit PHY register to write ++ * @device_type: 5 bit device type ++ * @phy_data: Data to write to the PHY register ++ **/ ++s32 ixgbe_write_phy_reg_mdio(struct ixgbe_hw *hw, u32 reg_addr, ++ u32 device_type, u16 phy_data) ++{ ++ u32 i, command; ++ ++ /* Put the data in the MDI single read and write data register*/ ++ IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data); ++ ++ /* Setup and write the write command */ ++ command = (reg_addr << IXGBE_MSCA_DEV_TYPE_SHIFT) | ++ (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) | ++ IXGBE_MSCA_OLD_PROTOCOL | IXGBE_MSCA_WRITE | ++ IXGBE_MSCA_MDI_COMMAND; ++ ++ IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); ++ ++ /* ++ * Check every 10 usec to see if the address cycle completed. ++ * The MDI Command bit will clear when the operation is ++ * complete ++ */ ++ for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { ++ udelay(10); ++ ++ command = IXGBE_READ_REG(hw, IXGBE_MSCA); ++ if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) ++ break; ++ } ++ ++ if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { ++ hw_dbg(hw, "PHY write cmd didn't complete\n"); ++ return IXGBE_ERR_PHY; ++ } ++ ++ return 0; ++} ++/** + * ixgbe_read_phy_mdi - Reads a value from a specified PHY register without + * the SWFW lock + * @hw: pointer to hardware structure +@@ -705,53 +790,52 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) + + ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg); + +- if (speed & IXGBE_LINK_SPEED_10GB_FULL) { +- /* Set or unset auto-negotiation 10G advertisement */ +- hw->phy.ops.read_reg(hw, MDIO_AN_10GBT_CTRL, +- MDIO_MMD_AN, +- &autoneg_reg); ++ /* Set or unset auto-negotiation 10G advertisement */ ++ hw->phy.ops.read_reg(hw, MDIO_AN_10GBT_CTRL, MDIO_MMD_AN, &autoneg_reg); + +- autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G; +- if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) +- autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G; ++ autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G; ++ if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) && ++ (speed & IXGBE_LINK_SPEED_10GB_FULL)) ++ autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G; + +- hw->phy.ops.write_reg(hw, MDIO_AN_10GBT_CTRL, +- MDIO_MMD_AN, +- autoneg_reg); +- } +- +- if (speed & IXGBE_LINK_SPEED_1GB_FULL) { +- /* Set or unset auto-negotiation 1G advertisement */ +- hw->phy.ops.read_reg(hw, +- IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, +- MDIO_MMD_AN, +- &autoneg_reg); ++ hw->phy.ops.write_reg(hw, MDIO_AN_10GBT_CTRL, MDIO_MMD_AN, autoneg_reg); + +- autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE; +- if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) +- autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE; ++ hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, ++ MDIO_MMD_AN, &autoneg_reg); + +- hw->phy.ops.write_reg(hw, +- IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, +- MDIO_MMD_AN, +- autoneg_reg); ++ if (hw->mac.type == ixgbe_mac_X550) { ++ /* Set or unset auto-negotiation 5G advertisement */ ++ autoneg_reg &= ~IXGBE_MII_5GBASE_T_ADVERTISE; ++ if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_5GB_FULL) && ++ (speed & IXGBE_LINK_SPEED_5GB_FULL)) ++ autoneg_reg |= IXGBE_MII_5GBASE_T_ADVERTISE; ++ ++ /* Set or unset auto-negotiation 2.5G advertisement */ ++ autoneg_reg &= ~IXGBE_MII_2_5GBASE_T_ADVERTISE; ++ if ((hw->phy.autoneg_advertised & ++ IXGBE_LINK_SPEED_2_5GB_FULL) && ++ (speed & IXGBE_LINK_SPEED_2_5GB_FULL)) ++ autoneg_reg |= IXGBE_MII_2_5GBASE_T_ADVERTISE; + } + +- if (speed & IXGBE_LINK_SPEED_100_FULL) { +- /* Set or unset auto-negotiation 100M advertisement */ +- hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, +- MDIO_MMD_AN, +- &autoneg_reg); ++ /* Set or unset auto-negotiation 1G advertisement */ ++ autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE; ++ if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) && ++ (speed & IXGBE_LINK_SPEED_1GB_FULL)) ++ autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE; + +- autoneg_reg &= ~(ADVERTISE_100FULL | +- ADVERTISE_100HALF); +- if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) +- autoneg_reg |= ADVERTISE_100FULL; ++ hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, ++ MDIO_MMD_AN, autoneg_reg); + +- hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, +- MDIO_MMD_AN, +- autoneg_reg); +- } ++ /* Set or unset auto-negotiation 100M advertisement */ ++ hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, &autoneg_reg); ++ ++ autoneg_reg &= ~(ADVERTISE_100FULL | ADVERTISE_100HALF); ++ if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) && ++ (speed & IXGBE_LINK_SPEED_100_FULL)) ++ autoneg_reg |= ADVERTISE_100FULL; ++ ++ hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, autoneg_reg); + + /* Blocked by MNG FW so don't reset PHY */ + if (ixgbe_check_reset_blocked(hw)) +@@ -778,9 +862,7 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete) + { +- +- /* +- * Clear autoneg_advertised and set new values based on input link ++ /* Clear autoneg_advertised and set new values based on input link + * speed. + */ + hw->phy.autoneg_advertised = 0; +@@ -788,14 +870,24 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, + if (speed & IXGBE_LINK_SPEED_10GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL; + ++ if (speed & IXGBE_LINK_SPEED_5GB_FULL) ++ hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_5GB_FULL; ++ ++ if (speed & IXGBE_LINK_SPEED_2_5GB_FULL) ++ hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_2_5GB_FULL; ++ + if (speed & IXGBE_LINK_SPEED_1GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL; + + if (speed & IXGBE_LINK_SPEED_100_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL; + ++ if (speed & IXGBE_LINK_SPEED_10_FULL) ++ hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10_FULL; ++ + /* Setup link based on the new speed settings */ +- hw->phy.ops.setup_link(hw); ++ if (hw->phy.ops.setup_link) ++ hw->phy.ops.setup_link(hw); + + return 0; + } +@@ -830,6 +922,7 @@ static s32 ixgbe_get_copper_speeds_supported(struct ixgbe_hw *hw) + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_5GB_FULL; + break; + case ixgbe_mac_X550EM_x: ++ case ixgbe_mac_x550em_a: + hw->phy.speeds_supported &= ~IXGBE_LINK_SPEED_100_FULL; + break; + default: +@@ -986,40 +1079,6 @@ s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw) + } + + /** +- * ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version +- * @hw: pointer to hardware structure +- * @firmware_version: pointer to the PHY Firmware Version +- **/ +-s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, +- u16 *firmware_version) +-{ +- s32 status; +- +- status = hw->phy.ops.read_reg(hw, TNX_FW_REV, +- MDIO_MMD_VEND1, +- firmware_version); +- +- return status; +-} +- +-/** +- * ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version +- * @hw: pointer to hardware structure +- * @firmware_version: pointer to the PHY Firmware Version +- **/ +-s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, +- u16 *firmware_version) +-{ +- s32 status; +- +- status = hw->phy.ops.read_reg(hw, AQ_FW_REV, +- MDIO_MMD_VEND1, +- firmware_version); +- +- return status; +-} +- +-/** + * ixgbe_reset_phy_nl - Performs a PHY reset + * @hw: pointer to hardware structure + **/ +@@ -2398,9 +2457,7 @@ s32 ixgbe_set_copper_phy_power(struct ixgbe_hw *hw, bool on) + if (!on && ixgbe_mng_present(hw)) + return 0; + +- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, +- ®); ++ status = hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_VEND1, ®); + if (status) + return status; + +@@ -2412,8 +2469,6 @@ s32 ixgbe_set_copper_phy_power(struct ixgbe_hw *hw, bool on) + reg |= IXGBE_MDIO_PHY_SET_LOW_POWER_MODE; + } + +- status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, +- reg); ++ status = hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_VEND1, reg); + return status; + } +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h +index cc735ec..e9f94ee 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h +@@ -84,8 +84,9 @@ + #define IXGBE_CS4227_GLOBAL_ID_LSB 0 + #define IXGBE_CS4227_GLOBAL_ID_MSB 1 + #define IXGBE_CS4227_SCRATCH 2 +-#define IXGBE_CS4223_PHY_ID 0x7003 /* Quad port */ +-#define IXGBE_CS4227_PHY_ID 0x3003 /* Dual port */ ++#define IXGBE_CS4227_EFUSE_PDF_SKU 0x19F ++#define IXGBE_CS4223_SKU_ID 0x0010 /* Quad port */ ++#define IXGBE_CS4227_SKU_ID 0x0014 /* Dual port */ + #define IXGBE_CS4227_RESET_PENDING 0x1357 + #define IXGBE_CS4227_RESET_COMPLETE 0x5AA5 + #define IXGBE_CS4227_RETRIES 15 +@@ -154,6 +155,12 @@ s32 ixgbe_read_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data); + s32 ixgbe_write_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data); ++#if 1 //by hilbert ++s32 ixgbe_read_phy_reg_mdio(struct ixgbe_hw *hw, u32 reg_addr, ++ u32 device_type, u16 *phy_data); ++s32 ixgbe_write_phy_reg_mdio(struct ixgbe_hw *hw, u32 reg_addr, ++ u32 device_type, u16 phy_data); ++#endif + s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw); + s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, + ixgbe_link_speed speed, +@@ -168,10 +175,6 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *link_up); + s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw); +-s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, +- u16 *firmware_version); +-s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, +- u16 *firmware_version); + + s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw); + s32 ixgbe_set_copper_phy_power(struct ixgbe_hw *hw, bool on); +@@ -195,12 +198,8 @@ s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 *sff8472_data); + s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 eeprom_data); +-s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr, +- u16 reg, u16 *val); +-s32 ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr, +- u16 reg, u16 *val); +-s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr, +- u16 reg, u16 val); +-s32 ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr, +- u16 reg, u16 val); ++s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *, u8 addr, u16 reg, ++ u16 *val, bool lock); ++s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *, u8 addr, u16 reg, ++ u16 val, bool lock); + #endif /* _IXGBE_PHY_H_ */ +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +index 31d82e3..531990b 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +@@ -85,6 +85,7 @@ + #define IXGBE_DEV_ID_X550EM_X_SFP 0x15AC + #define IXGBE_DEV_ID_X550EM_X_10G_T 0x15AD + #define IXGBE_DEV_ID_X550EM_X_1G_T 0x15AE ++#define IXGBE_DEV_ID_X550EM_X_XFI 0x15B0 + #define IXGBE_DEV_ID_X550EM_A_KR 0x15C2 + #define IXGBE_DEV_ID_X550EM_A_KR_L 0x15C3 + #define IXGBE_DEV_ID_X550EM_A_SFP_N 0x15C4 +@@ -92,6 +93,8 @@ + #define IXGBE_DEV_ID_X550EM_A_SGMII_L 0x15C7 + #define IXGBE_DEV_ID_X550EM_A_10G_T 0x15C8 + #define IXGBE_DEV_ID_X550EM_A_SFP 0x15CE ++#define IXGBE_DEV_ID_X550EM_A_1G_T 0x15E4 ++#define IXGBE_DEV_ID_X550EM_A_1G_T_L 0x15E5 + + /* VF Device IDs */ + #define IXGBE_DEV_ID_82599_VF 0x10ED +@@ -1393,8 +1396,10 @@ struct ixgbe_thermal_sensor_data { + #define TN1010_PHY_ID 0x00A19410 + #define TNX_FW_REV 0xB + #define X540_PHY_ID 0x01540200 +-#define X550_PHY_ID 0x01540220 ++#define X550_PHY_ID2 0x01540223 ++#define X550_PHY_ID3 0x01540221 + #define X557_PHY_ID 0x01540240 ++#define X557_PHY_ID2 0x01540250 + #define QT2022_PHY_ID 0x0043A400 + #define ATH_PHY_ID 0x03429050 + #define AQ_FW_REV 0x20 +@@ -1513,6 +1518,8 @@ enum { + #define IXGBE_VT_CTL_POOL_MASK (0x3F << IXGBE_VT_CTL_POOL_SHIFT) + + /* VMOLR bitmasks */ ++#define IXGBE_VMOLR_UPE 0x00400000 /* unicast promiscuous */ ++#define IXGBE_VMOLR_VPE 0x00800000 /* VLAN promiscuous */ + #define IXGBE_VMOLR_AUPE 0x01000000 /* accept untagged packets */ + #define IXGBE_VMOLR_ROMPE 0x02000000 /* accept packets in MTA tbl */ + #define IXGBE_VMOLR_ROPE 0x04000000 /* accept packets in UC tbl */ +@@ -1928,6 +1935,7 @@ enum { + #define IXGBE_LINKS_SPEED_10G_82599 0x30000000 + #define IXGBE_LINKS_SPEED_1G_82599 0x20000000 + #define IXGBE_LINKS_SPEED_100_82599 0x10000000 ++#define IXGBE_LINKS_SPEED_10_X550EM_A 0 + #define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */ + #define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */ + +@@ -2633,6 +2641,7 @@ enum ixgbe_fdir_pballoc_type { + #define FW_CEM_UNUSED_VER 0x0 + #define FW_CEM_MAX_RETRIES 3 + #define FW_CEM_RESP_STATUS_SUCCESS 0x1 ++#define FW_CEM_DRIVER_VERSION_SIZE 39 /* +9 would send 48 bytes to fw */ + #define FW_READ_SHADOW_RAM_CMD 0x31 + #define FW_READ_SHADOW_RAM_LEN 0x6 + #define FW_WRITE_SHADOW_RAM_CMD 0x33 +@@ -2658,6 +2667,59 @@ enum ixgbe_fdir_pballoc_type { + #define FW_INT_PHY_REQ_LEN 10 + #define FW_INT_PHY_REQ_READ 0 + #define FW_INT_PHY_REQ_WRITE 1 ++#define FW_PHY_ACT_REQ_CMD 5 ++#define FW_PHY_ACT_DATA_COUNT 4 ++#define FW_PHY_ACT_REQ_LEN (4 + 4 * FW_PHY_ACT_DATA_COUNT) ++#define FW_PHY_ACT_INIT_PHY 1 ++#define FW_PHY_ACT_SETUP_LINK 2 ++#define FW_PHY_ACT_LINK_SPEED_10 BIT(0) ++#define FW_PHY_ACT_LINK_SPEED_100 BIT(1) ++#define FW_PHY_ACT_LINK_SPEED_1G BIT(2) ++#define FW_PHY_ACT_LINK_SPEED_2_5G BIT(3) ++#define FW_PHY_ACT_LINK_SPEED_5G BIT(4) ++#define FW_PHY_ACT_LINK_SPEED_10G BIT(5) ++#define FW_PHY_ACT_LINK_SPEED_20G BIT(6) ++#define FW_PHY_ACT_LINK_SPEED_25G BIT(7) ++#define FW_PHY_ACT_LINK_SPEED_40G BIT(8) ++#define FW_PHY_ACT_LINK_SPEED_50G BIT(9) ++#define FW_PHY_ACT_LINK_SPEED_100G BIT(10) ++#define FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT 16 ++#define FW_PHY_ACT_SETUP_LINK_PAUSE_MASK (3 << \ ++ HW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT) ++#define FW_PHY_ACT_SETUP_LINK_PAUSE_NONE 0u ++#define FW_PHY_ACT_SETUP_LINK_PAUSE_TX 1u ++#define FW_PHY_ACT_SETUP_LINK_PAUSE_RX 2u ++#define FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX 3u ++#define FW_PHY_ACT_SETUP_LINK_LP BIT(18) ++#define FW_PHY_ACT_SETUP_LINK_HP BIT(19) ++#define FW_PHY_ACT_SETUP_LINK_EEE BIT(20) ++#define FW_PHY_ACT_SETUP_LINK_AN BIT(22) ++#define FW_PHY_ACT_SETUP_LINK_RSP_DOWN BIT(0) ++#define FW_PHY_ACT_GET_LINK_INFO 3 ++#define FW_PHY_ACT_GET_LINK_INFO_EEE BIT(19) ++#define FW_PHY_ACT_GET_LINK_INFO_FC_TX BIT(20) ++#define FW_PHY_ACT_GET_LINK_INFO_FC_RX BIT(21) ++#define FW_PHY_ACT_GET_LINK_INFO_POWER BIT(22) ++#define FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE BIT(24) ++#define FW_PHY_ACT_GET_LINK_INFO_TEMP BIT(25) ++#define FW_PHY_ACT_GET_LINK_INFO_LP_FC_TX BIT(28) ++#define FW_PHY_ACT_GET_LINK_INFO_LP_FC_RX BIT(29) ++#define FW_PHY_ACT_FORCE_LINK_DOWN 4 ++#define FW_PHY_ACT_FORCE_LINK_DOWN_OFF BIT(0) ++#define FW_PHY_ACT_PHY_SW_RESET 5 ++#define FW_PHY_ACT_PHY_HW_RESET 6 ++#define FW_PHY_ACT_GET_PHY_INFO 7 ++#define FW_PHY_ACT_UD_2 0x1002 ++#define FW_PHY_ACT_UD_2_10G_KR_EEE BIT(6) ++#define FW_PHY_ACT_UD_2_10G_KX4_EEE BIT(5) ++#define FW_PHY_ACT_UD_2_1G_KX_EEE BIT(4) ++#define FW_PHY_ACT_UD_2_10G_T_EEE BIT(3) ++#define FW_PHY_ACT_UD_2_1G_T_EEE BIT(2) ++#define FW_PHY_ACT_UD_2_100M_TX_EEE BIT(1) ++#define FW_PHY_ACT_RETRIES 50 ++#define FW_PHY_INFO_SPEED_MASK 0xFFFu ++#define FW_PHY_INFO_ID_HI_MASK 0xFFFF0000u ++#define FW_PHY_INFO_ID_LO_MASK 0x0000FFFFu + + /* Host Interface Command Structures */ + struct ixgbe_hic_hdr { +@@ -2700,6 +2762,16 @@ struct ixgbe_hic_drv_info { + u16 pad2; /* end spacing to ensure length is mult. of dword2 */ + }; + ++struct ixgbe_hic_drv_info2 { ++ struct ixgbe_hic_hdr hdr; ++ u8 port_num; ++ u8 ver_sub; ++ u8 ver_build; ++ u8 ver_min; ++ u8 ver_maj; ++ char driver_string[FW_CEM_DRIVER_VERSION_SIZE]; ++}; ++ + /* These need to be dword aligned */ + struct ixgbe_hic_read_shadow_ram { + union ixgbe_hic_hdr2 hdr; +@@ -2748,6 +2820,19 @@ struct ixgbe_hic_internal_phy_resp { + __be32 read_data; + }; + ++struct ixgbe_hic_phy_activity_req { ++ struct ixgbe_hic_hdr hdr; ++ u8 port_number; ++ u8 pad; ++ __le16 activity_id; ++ __be32 data[FW_PHY_ACT_DATA_COUNT]; ++}; ++ ++struct ixgbe_hic_phy_activity_resp { ++ struct ixgbe_hic_hdr hdr; ++ __be32 data[FW_PHY_ACT_DATA_COUNT]; ++}; ++ + /* Transmit Descriptor - Advanced */ + union ixgbe_adv_tx_desc { + struct { +@@ -2863,6 +2948,7 @@ typedef u32 ixgbe_autoneg_advertised; + /* Link speed */ + typedef u32 ixgbe_link_speed; + #define IXGBE_LINK_SPEED_UNKNOWN 0 ++#define IXGBE_LINK_SPEED_10_FULL 0x0002 + #define IXGBE_LINK_SPEED_100_FULL 0x0008 + #define IXGBE_LINK_SPEED_1GB_FULL 0x0020 + #define IXGBE_LINK_SPEED_2_5GB_FULL 0x0400 +@@ -3059,7 +3145,9 @@ enum ixgbe_phy_type { + ixgbe_phy_aq, + ixgbe_phy_x550em_kr, + ixgbe_phy_x550em_kx4, ++ ixgbe_phy_x550em_xfi, + ixgbe_phy_x550em_ext_t, ++ ixgbe_phy_ext_1g_t, + ixgbe_phy_cu_unknown, + ixgbe_phy_qt, + ixgbe_phy_xaui, +@@ -3078,6 +3166,7 @@ enum ixgbe_phy_type { + ixgbe_phy_qsfp_unknown, + ixgbe_phy_sfp_unsupported, + ixgbe_phy_sgmii, ++ ixgbe_phy_fw, + ixgbe_phy_generic + }; + +@@ -3352,6 +3441,7 @@ struct ixgbe_mac_operations { + s32 (*led_off)(struct ixgbe_hw *, u32); + s32 (*blink_led_start)(struct ixgbe_hw *, u32); + s32 (*blink_led_stop)(struct ixgbe_hw *, u32); ++ s32 (*init_led_link_act)(struct ixgbe_hw *); + + /* RAR, Multicast, VLAN */ + s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32, u32); +@@ -3372,9 +3462,11 @@ struct ixgbe_mac_operations { + /* Flow Control */ + s32 (*fc_enable)(struct ixgbe_hw *); + s32 (*setup_fc)(struct ixgbe_hw *); ++ void (*fc_autoneg)(struct ixgbe_hw *); + + /* Manageability interface */ +- s32 (*set_fw_drv_ver)(struct ixgbe_hw *, u8, u8, u8, u8); ++ s32 (*set_fw_drv_ver)(struct ixgbe_hw *, u8, u8, u8, u8, u16, ++ const char *); + s32 (*get_thermal_sensor_data)(struct ixgbe_hw *); + s32 (*init_thermal_sensor_thresh)(struct ixgbe_hw *hw); + void (*disable_rx)(struct ixgbe_hw *hw); +@@ -3416,10 +3508,24 @@ struct ixgbe_phy_operations { + s32 (*set_phy_power)(struct ixgbe_hw *, bool on); + s32 (*enter_lplu)(struct ixgbe_hw *); + s32 (*handle_lasi)(struct ixgbe_hw *hw); +- s32 (*read_i2c_combined_unlocked)(struct ixgbe_hw *, u8 addr, u16 reg, +- u16 *value); +- s32 (*write_i2c_combined_unlocked)(struct ixgbe_hw *, u8 addr, u16 reg, +- u16 value); ++ s32 (*read_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr, ++ u8 *value); ++ s32 (*write_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr, ++ u8 value); ++}; ++ ++struct ixgbe_link_operations { ++ s32 (*read_link)(struct ixgbe_hw *, u8 addr, u16 reg, u16 *val); ++ s32 (*read_link_unlocked)(struct ixgbe_hw *, u8 addr, u16 reg, ++ u16 *val); ++ s32 (*write_link)(struct ixgbe_hw *, u8 addr, u16 reg, u16 val); ++ s32 (*write_link_unlocked)(struct ixgbe_hw *, u8 addr, u16 reg, ++ u16 val); ++}; ++ ++struct ixgbe_link_info { ++ struct ixgbe_link_operations ops; ++ u8 addr; + }; + + struct ixgbe_eeprom_info { +@@ -3462,6 +3568,7 @@ struct ixgbe_mac_info { + u8 san_mac_rar_index; + struct ixgbe_thermal_sensor_data thermal_sensor_data; + bool set_lben; ++ u8 led_link_act; + }; + + struct ixgbe_phy_info { +@@ -3477,6 +3584,8 @@ struct ixgbe_phy_info { + bool reset_disable; + ixgbe_autoneg_advertised autoneg_advertised; + ixgbe_link_speed speeds_supported; ++ ixgbe_link_speed eee_speeds_supported; ++ ixgbe_link_speed eee_speeds_advertised; + enum ixgbe_smart_speed smart_speed; + bool smart_speed_active; + bool multispeed_fiber; +@@ -3523,6 +3632,7 @@ struct ixgbe_hw { + struct ixgbe_addr_filter_info addr_ctrl; + struct ixgbe_fc_info fc; + struct ixgbe_phy_info phy; ++ struct ixgbe_link_info link; + struct ixgbe_eeprom_info eeprom; + struct ixgbe_bus_info bus; + struct ixgbe_mbx_info mbx; +@@ -3546,6 +3656,7 @@ struct ixgbe_info { + const struct ixgbe_eeprom_operations *eeprom_ops; + const struct ixgbe_phy_operations *phy_ops; + const struct ixgbe_mbx_operations *mbx_ops; ++ const struct ixgbe_link_operations *link_ops; + const u32 *mvals; + }; + +@@ -3593,17 +3704,35 @@ struct ixgbe_info { + #define IXGBE_FUSES0_REV_MASK (3u << 6) + + #define IXGBE_KRM_PORT_CAR_GEN_CTRL(P) ((P) ? 0x8010 : 0x4010) ++#define IXGBE_KRM_LINK_S1(P) ((P) ? 0x8200 : 0x4200) + #define IXGBE_KRM_LINK_CTRL_1(P) ((P) ? 0x820C : 0x420C) + #define IXGBE_KRM_AN_CNTL_1(P) ((P) ? 0x822C : 0x422C) + #define IXGBE_KRM_AN_CNTL_8(P) ((P) ? 0x8248 : 0x4248) + #define IXGBE_KRM_SGMII_CTRL(P) ((P) ? 0x82A0 : 0x42A0) ++#define IXGBE_KRM_LP_BASE_PAGE_HIGH(P) ((P) ? 0x836C : 0x436C) + #define IXGBE_KRM_DSP_TXFFE_STATE_4(P) ((P) ? 0x8634 : 0x4634) + #define IXGBE_KRM_DSP_TXFFE_STATE_5(P) ((P) ? 0x8638 : 0x4638) + #define IXGBE_KRM_RX_TRN_LINKUP_CTRL(P) ((P) ? 0x8B00 : 0x4B00) + #define IXGBE_KRM_PMD_DFX_BURNIN(P) ((P) ? 0x8E00 : 0x4E00) ++#define IXGBE_KRM_PMD_FLX_MASK_ST20(P) ((P) ? 0x9054 : 0x5054) + #define IXGBE_KRM_TX_COEFF_CTRL_1(P) ((P) ? 0x9520 : 0x5520) + #define IXGBE_KRM_RX_ANA_CTL(P) ((P) ? 0x9A00 : 0x5A00) + ++#define IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA ~(0x3 << 20) ++#define IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR BIT(20) ++#define IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_LR (0x2 << 20) ++#define IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN BIT(25) ++#define IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN BIT(26) ++#define IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN BIT(27) ++#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10M ~(0x7 << 28) ++#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_100M BIT(28) ++#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G (0x2 << 28) ++#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G (0x3 << 28) ++#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN (0x4 << 28) ++#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_2_5G (0x7 << 28) ++#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK (0x7 << 28) ++#define IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART BIT(31) ++ + #define IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B BIT(9) + #define IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS BIT(11) + +@@ -3618,6 +3747,7 @@ struct ixgbe_info { + #define IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR BIT(18) + #define IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX BIT(24) + #define IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR BIT(26) ++#define IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE BIT(28) + #define IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE BIT(29) + #define IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART BIT(31) + +@@ -3627,6 +3757,8 @@ struct ixgbe_info { + #define IXGBE_KRM_AN_CNTL_8_LINEAR BIT(0) + #define IXGBE_KRM_AN_CNTL_8_LIMITING BIT(1) + ++#define IXGBE_KRM_LP_BASE_PAGE_HIGH_SYM_PAUSE BIT(10) ++#define IXGBE_KRM_LP_BASE_PAGE_HIGH_ASM_PAUSE BIT(11) + #define IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D BIT(12) + #define IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D BIT(19) + +@@ -3675,8 +3807,13 @@ struct ixgbe_info { + + #define IXGBE_NW_MNG_IF_SEL 0x00011178 + #define IXGBE_NW_MNG_IF_SEL_MDIO_ACT BIT(1) +-#define IXGBE_NW_MNG_IF_SEL_ENABLE_10_100M BIT(23) +-#define IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE BIT(24) ++#define IXGBE_NW_MNG_IF_SEL_PHY_SPEED_10M BIT(17) ++#define IXGBE_NW_MNG_IF_SEL_PHY_SPEED_100M BIT(18) ++#define IXGBE_NW_MNG_IF_SEL_PHY_SPEED_1G BIT(19) ++#define IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G BIT(20) ++#define IXGBE_NW_MNG_IF_SEL_PHY_SPEED_10G BIT(21) ++#define IXGBE_NW_MNG_IF_SEL_SGMII_ENABLE BIT(25) ++#define IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE BIT(24) /* X552 only */ + #define IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT 3 + #define IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD \ + (0x1F << IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT) +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c +index f2b1d48..6ea0d6a 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c +@@ -95,6 +95,7 @@ s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) + { + s32 status; + u32 ctrl, i; ++ u32 swfw_mask = hw->phy.phy_semaphore_mask; + + /* Call adapter stop to disable tx/rx and clear interrupts */ + status = hw->mac.ops.stop_adapter(hw); +@@ -105,10 +106,17 @@ s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) + ixgbe_clear_tx_pending(hw); + + mac_reset_top: ++ status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); ++ if (status) { ++ hw_dbg(hw, "semaphore failed with %d", status); ++ return IXGBE_ERR_SWFW_SYNC; ++ } ++ + ctrl = IXGBE_CTRL_RST; + ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); + IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); + IXGBE_WRITE_FLUSH(hw); ++ hw->mac.ops.release_swfw_sync(hw, swfw_mask); + usleep_range(1000, 1200); + + /* Poll for reset bit to self-clear indicating reset is complete */ +@@ -780,8 +788,10 @@ s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index) + ixgbe_link_speed speed; + bool link_up; + +- /* +- * Link should be up in order for the blink bit in the LED control ++ if (index > 3) ++ return IXGBE_ERR_PARAM; ++ ++ /* Link should be up in order for the blink bit in the LED control + * register to work. Force link and speed in the MAC if link is down. + * This will be reversed when we stop the blinking. + */ +@@ -814,6 +824,9 @@ s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index) + u32 macc_reg; + u32 ledctl_reg; + ++ if (index > 3) ++ return IXGBE_ERR_PARAM; ++ + /* Restore the LED to its default value. */ + ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + ledctl_reg &= ~IXGBE_LED_MODE_MASK(index); +@@ -851,6 +864,7 @@ static const struct ixgbe_mac_operations mac_ops_X540 = { + .get_link_capabilities = &ixgbe_get_copper_link_capabilities_generic, + .led_on = &ixgbe_led_on_generic, + .led_off = &ixgbe_led_off_generic, ++ .init_led_link_act = ixgbe_init_led_link_act_generic, + .blink_led_start = &ixgbe_blink_led_start_X540, + .blink_led_stop = &ixgbe_blink_led_stop_X540, + .set_rar = &ixgbe_set_rar_generic, +@@ -866,6 +880,7 @@ static const struct ixgbe_mac_operations mac_ops_X540 = { + .set_vfta = &ixgbe_set_vfta_generic, + .fc_enable = &ixgbe_fc_enable_generic, + .setup_fc = ixgbe_setup_fc_generic, ++ .fc_autoneg = ixgbe_fc_autoneg, + .set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic, + .init_uta_tables = &ixgbe_init_uta_tables_generic, + .setup_sfp = NULL, +@@ -911,7 +926,6 @@ static const struct ixgbe_phy_operations phy_ops_X540 = { + .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic, + .check_overtemp = &ixgbe_tn_check_overtemp, + .set_phy_power = &ixgbe_set_copper_phy_power, +- .get_firmware_version = &ixgbe_get_phy_firmware_version_generic, + }; + + static const u32 ixgbe_mvals_X540[IXGBE_MVALS_IDX_LIMIT] = { +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +index 77a60aa..3236248 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +@@ -28,11 +28,15 @@ + + static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *, ixgbe_link_speed); + static s32 ixgbe_setup_fc_x550em(struct ixgbe_hw *); ++static void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *); ++static void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *); ++static s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *); + + static s32 ixgbe_get_invariants_X550_x(struct ixgbe_hw *hw) + { + struct ixgbe_mac_info *mac = &hw->mac; + struct ixgbe_phy_info *phy = &hw->phy; ++ struct ixgbe_link_info *link = &hw->link; + + /* Start with X540 invariants, since so simular */ + ixgbe_get_invariants_X540(hw); +@@ -40,6 +44,46 @@ static s32 ixgbe_get_invariants_X550_x(struct ixgbe_hw *hw) + if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper) + phy->ops.set_phy_power = NULL; + ++ link->addr = IXGBE_CS4227; ++ ++ return 0; ++} ++ ++static s32 ixgbe_get_invariants_X550_x_fw(struct ixgbe_hw *hw) ++{ ++ struct ixgbe_phy_info *phy = &hw->phy; ++ ++ /* Start with X540 invariants, since so similar */ ++ ixgbe_get_invariants_X540(hw); ++ ++ phy->ops.set_phy_power = NULL; ++ ++ return 0; ++} ++ ++static s32 ixgbe_get_invariants_X550_a(struct ixgbe_hw *hw) ++{ ++ struct ixgbe_mac_info *mac = &hw->mac; ++ struct ixgbe_phy_info *phy = &hw->phy; ++ ++ /* Start with X540 invariants, since so simular */ ++ ixgbe_get_invariants_X540(hw); ++ ++ if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper) ++ phy->ops.set_phy_power = NULL; ++ ++ return 0; ++} ++ ++static s32 ixgbe_get_invariants_X550_a_fw(struct ixgbe_hw *hw) ++{ ++ struct ixgbe_phy_info *phy = &hw->phy; ++ ++ /* Start with X540 invariants, since so similar */ ++ ixgbe_get_invariants_X540(hw); ++ ++ phy->ops.set_phy_power = NULL; ++ + return 0; + } + +@@ -69,8 +113,7 @@ static void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw) + */ + static s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value) + { +- return hw->phy.ops.read_i2c_combined_unlocked(hw, IXGBE_CS4227, reg, +- value); ++ return hw->link.ops.read_link_unlocked(hw, hw->link.addr, reg, value); + } + + /** +@@ -83,8 +126,7 @@ static s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value) + */ + static s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value) + { +- return hw->phy.ops.write_i2c_combined_unlocked(hw, IXGBE_CS4227, reg, +- value); ++ return hw->link.ops.write_link_unlocked(hw, hw->link.addr, reg, value); + } + + /** +@@ -290,6 +332,9 @@ static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw) + case IXGBE_DEV_ID_X550EM_X_KX4: + hw->phy.type = ixgbe_phy_x550em_kx4; + break; ++ case IXGBE_DEV_ID_X550EM_X_XFI: ++ hw->phy.type = ixgbe_phy_x550em_xfi; ++ break; + case IXGBE_DEV_ID_X550EM_X_KR: + case IXGBE_DEV_ID_X550EM_A_KR: + case IXGBE_DEV_ID_X550EM_A_KR_L: +@@ -301,9 +346,21 @@ static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw) + else + hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM; + /* Fallthrough */ +- case IXGBE_DEV_ID_X550EM_X_1G_T: + case IXGBE_DEV_ID_X550EM_X_10G_T: + return ixgbe_identify_phy_generic(hw); ++ case IXGBE_DEV_ID_X550EM_X_1G_T: ++ hw->phy.type = ixgbe_phy_ext_1g_t; ++ break; ++ case IXGBE_DEV_ID_X550EM_A_1G_T: ++ case IXGBE_DEV_ID_X550EM_A_1G_T_L: ++ hw->phy.type = ixgbe_phy_fw; ++ hw->phy.ops.read_reg = NULL; ++ hw->phy.ops.write_reg = NULL; ++ if (hw->bus.lan_id) ++ hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM; ++ else ++ hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM; ++ break; + default: + break; + } +@@ -322,6 +379,280 @@ static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr, + return IXGBE_NOT_IMPLEMENTED; + } + ++/** ++ * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation ++ * @hw: pointer to the hardware structure ++ * @addr: I2C bus address to read from ++ * @reg: I2C device register to read from ++ * @val: pointer to location to receive read value ++ * ++ * Returns an error code on error. ++ **/ ++static s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr, ++ u16 reg, u16 *val) ++{ ++ return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, true); ++} ++ ++/** ++ * ixgbe_read_i2c_combined_generic_unlocked - Do I2C read combined operation ++ * @hw: pointer to the hardware structure ++ * @addr: I2C bus address to read from ++ * @reg: I2C device register to read from ++ * @val: pointer to location to receive read value ++ * ++ * Returns an error code on error. ++ **/ ++static s32 ++ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr, ++ u16 reg, u16 *val) ++{ ++ return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, false); ++} ++ ++/** ++ * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation ++ * @hw: pointer to the hardware structure ++ * @addr: I2C bus address to write to ++ * @reg: I2C device register to write to ++ * @val: value to write ++ * ++ * Returns an error code on error. ++ **/ ++static s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw, ++ u8 addr, u16 reg, u16 val) ++{ ++ return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, true); ++} ++ ++/** ++ * ixgbe_write_i2c_combined_generic_unlocked - Do I2C write combined operation ++ * @hw: pointer to the hardware structure ++ * @addr: I2C bus address to write to ++ * @reg: I2C device register to write to ++ * @val: value to write ++ * ++ * Returns an error code on error. ++ **/ ++static s32 ++ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, ++ u8 addr, u16 reg, u16 val) ++{ ++ return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, false); ++} ++ ++/** ++ * ixgbe_fw_phy_activity - Perform an activity on a PHY ++ * @hw: pointer to hardware structure ++ * @activity: activity to perform ++ * @data: Pointer to 4 32-bit words of data ++ */ ++s32 ixgbe_fw_phy_activity(struct ixgbe_hw *hw, u16 activity, ++ u32 (*data)[FW_PHY_ACT_DATA_COUNT]) ++{ ++ union { ++ struct ixgbe_hic_phy_activity_req cmd; ++ struct ixgbe_hic_phy_activity_resp rsp; ++ } hic; ++ u16 retries = FW_PHY_ACT_RETRIES; ++ s32 rc; ++ u32 i; ++ ++ do { ++ memset(&hic, 0, sizeof(hic)); ++ hic.cmd.hdr.cmd = FW_PHY_ACT_REQ_CMD; ++ hic.cmd.hdr.buf_len = FW_PHY_ACT_REQ_LEN; ++ hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; ++ hic.cmd.port_number = hw->bus.lan_id; ++ hic.cmd.activity_id = cpu_to_le16(activity); ++ for (i = 0; i < ARRAY_SIZE(hic.cmd.data); ++i) ++ hic.cmd.data[i] = cpu_to_be32((*data)[i]); ++ ++ rc = ixgbe_host_interface_command(hw, &hic.cmd, sizeof(hic.cmd), ++ IXGBE_HI_COMMAND_TIMEOUT, ++ true); ++ if (rc) ++ return rc; ++ if (hic.rsp.hdr.cmd_or_resp.ret_status == ++ FW_CEM_RESP_STATUS_SUCCESS) { ++ for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i) ++ (*data)[i] = be32_to_cpu(hic.rsp.data[i]); ++ return 0; ++ } ++ usleep_range(20, 30); ++ --retries; ++ } while (retries > 0); ++ ++ return IXGBE_ERR_HOST_INTERFACE_COMMAND; ++} ++ ++static const struct { ++ u16 fw_speed; ++ ixgbe_link_speed phy_speed; ++} ixgbe_fw_map[] = { ++ { FW_PHY_ACT_LINK_SPEED_10, IXGBE_LINK_SPEED_10_FULL }, ++ { FW_PHY_ACT_LINK_SPEED_100, IXGBE_LINK_SPEED_100_FULL }, ++ { FW_PHY_ACT_LINK_SPEED_1G, IXGBE_LINK_SPEED_1GB_FULL }, ++ { FW_PHY_ACT_LINK_SPEED_2_5G, IXGBE_LINK_SPEED_2_5GB_FULL }, ++ { FW_PHY_ACT_LINK_SPEED_5G, IXGBE_LINK_SPEED_5GB_FULL }, ++ { FW_PHY_ACT_LINK_SPEED_10G, IXGBE_LINK_SPEED_10GB_FULL }, ++}; ++ ++/** ++ * ixgbe_get_phy_id_fw - Get the phy ID via firmware command ++ * @hw: pointer to hardware structure ++ * ++ * Returns error code ++ */ ++static s32 ixgbe_get_phy_id_fw(struct ixgbe_hw *hw) ++{ ++ u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 }; ++ u16 phy_speeds; ++ u16 phy_id_lo; ++ s32 rc; ++ u16 i; ++ ++ if (hw->phy.id) ++ return 0; ++ ++ rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_PHY_INFO, &info); ++ if (rc) ++ return rc; ++ ++ hw->phy.speeds_supported = 0; ++ phy_speeds = info[0] & FW_PHY_INFO_SPEED_MASK; ++ for (i = 0; i < ARRAY_SIZE(ixgbe_fw_map); ++i) { ++ if (phy_speeds & ixgbe_fw_map[i].fw_speed) ++ hw->phy.speeds_supported |= ixgbe_fw_map[i].phy_speed; ++ } ++ ++ hw->phy.id = info[0] & FW_PHY_INFO_ID_HI_MASK; ++ phy_id_lo = info[1] & FW_PHY_INFO_ID_LO_MASK; ++ hw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK; ++ hw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK; ++ if (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK) ++ return IXGBE_ERR_PHY_ADDR_INVALID; ++ ++ hw->phy.autoneg_advertised = hw->phy.speeds_supported; ++ hw->phy.eee_speeds_supported = IXGBE_LINK_SPEED_100_FULL | ++ IXGBE_LINK_SPEED_1GB_FULL; ++ hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported; ++ return 0; ++} ++ ++static s32 ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, ++ u32 device_type, u16 *phy_data); ++/** ++ * ixgbe_identify_phy_fw - Get PHY type based on firmware command ++ * @hw: pointer to hardware structure ++ * ++ * Returns error code ++ */ ++static s32 ixgbe_identify_phy_fw(struct ixgbe_hw *hw) ++{ ++ s32 rc; ++ u16 value=0; ++ ++ if (hw->bus.lan_id) ++ hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM; ++ else ++ hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM; ++ ++#if 0 /* Try also to get PHY ID through MDIO by using C22 in read_reg op. ++ * By hilbert ++ */ ++ rc = hw->phy.ops.read_reg(hw, MDIO_DEVID1, MDIO_MMD_PMAPMD, &value); ++ hw_err(hw, "####rc:%x, PHY ID-1:%x\n", rc, value); ++#endif ++ ++ hw->phy.type = ixgbe_phy_fw; ++#if 0 /* We still need read/write ops later, don't NULL it. By hilbert */ ++ hw->phy.ops.read_reg = NULL; ++ hw->phy.ops.write_reg = NULL; ++#endif ++ return ixgbe_get_phy_id_fw(hw); ++} ++ ++/** ++ * ixgbe_shutdown_fw_phy - Shutdown a firmware-controlled PHY ++ * @hw: pointer to hardware structure ++ * ++ * Returns error code ++ */ ++static s32 ixgbe_shutdown_fw_phy(struct ixgbe_hw *hw) ++{ ++ u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 }; ++ ++ setup[0] = FW_PHY_ACT_FORCE_LINK_DOWN_OFF; ++ return ixgbe_fw_phy_activity(hw, FW_PHY_ACT_FORCE_LINK_DOWN, &setup); ++} ++ ++/** ++ * ixgbe_setup_fw_link - Setup firmware-controlled PHYs ++ * @hw: pointer to hardware structure ++ */ ++static s32 ixgbe_setup_fw_link(struct ixgbe_hw *hw) ++{ ++ u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 }; ++ s32 rc; ++ u16 i; ++ ++ if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw)) ++ return 0; ++ ++ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { ++ hw_err(hw, "rx_pause not valid in strict IEEE mode\n"); ++ return IXGBE_ERR_INVALID_LINK_SETTINGS; ++ } ++ ++ switch (hw->fc.requested_mode) { ++ case ixgbe_fc_full: ++ setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX << ++ FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT; ++ break; ++ case ixgbe_fc_rx_pause: ++ setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RX << ++ FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT; ++ break; ++ case ixgbe_fc_tx_pause: ++ setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_TX << ++ FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT; ++ break; ++ default: ++ break; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(ixgbe_fw_map); ++i) { ++ if (hw->phy.autoneg_advertised & ixgbe_fw_map[i].phy_speed) ++ setup[0] |= ixgbe_fw_map[i].fw_speed; ++ } ++ setup[0] |= FW_PHY_ACT_SETUP_LINK_HP | FW_PHY_ACT_SETUP_LINK_AN; ++ ++ if (hw->phy.eee_speeds_advertised) ++ setup[0] |= FW_PHY_ACT_SETUP_LINK_EEE; ++ ++ rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup); ++ if (rc) ++ return rc; ++ if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN) ++ return IXGBE_ERR_OVERTEMP; ++ return 0; ++} ++ ++/** ++ * ixgbe_fc_autoneg_fw - Set up flow control for FW-controlled PHYs ++ * @hw: pointer to hardware structure ++ * ++ * Called at init time to set up flow control. ++ */ ++static s32 ixgbe_fc_autoneg_fw(struct ixgbe_hw *hw) ++{ ++ if (hw->fc.requested_mode == ixgbe_fc_default) ++ hw->fc.requested_mode = ixgbe_fc_full; ++ ++ return ixgbe_setup_fw_link(hw); ++} ++ + /** ixgbe_init_eeprom_params_X550 - Initialize EEPROM params + * @hw: pointer to hardware structure + * +@@ -544,41 +875,6 @@ static s32 ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + return status; + } + +-/** ixgbe_read_ee_hostif_data_X550 - Read EEPROM word using a host interface +- * command assuming that the semaphore is already obtained. +- * @hw: pointer to hardware structure +- * @offset: offset of word in the EEPROM to read +- * @data: word read from the EEPROM +- * +- * Reads a 16 bit word from the EEPROM using the hostif. +- **/ +-static s32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset, +- u16 *data) +-{ +- s32 status; +- struct ixgbe_hic_read_shadow_ram buffer; +- +- buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD; +- buffer.hdr.req.buf_lenh = 0; +- buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN; +- buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM; +- +- /* convert offset from words to bytes */ +- buffer.address = cpu_to_be32(offset * 2); +- /* one word */ +- buffer.length = cpu_to_be16(sizeof(u16)); +- +- status = ixgbe_host_interface_command(hw, &buffer, sizeof(buffer), +- IXGBE_HI_COMMAND_TIMEOUT, false); +- if (status) +- return status; +- +- *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, +- FW_NVM_DATA_OFFSET); +- +- return 0; +-} +- + /** ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read +@@ -590,6 +886,7 @@ static s32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset, + static s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, + u16 offset, u16 words, u16 *data) + { ++ const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM; + struct ixgbe_hic_read_shadow_ram buffer; + u32 current_word = 0; + u16 words_to_read; +@@ -597,7 +894,7 @@ static s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, + u32 i; + + /* Take semaphore for the entire operation. */ +- status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM); ++ status = hw->mac.ops.acquire_swfw_sync(hw, mask); + if (status) { + hw_dbg(hw, "EEPROM read buffer - semaphore failed\n"); + return status; +@@ -620,10 +917,8 @@ static s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, + buffer.pad2 = 0; + buffer.pad3 = 0; + +- status = ixgbe_host_interface_command(hw, &buffer, +- sizeof(buffer), +- IXGBE_HI_COMMAND_TIMEOUT, +- false); ++ status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer), ++ IXGBE_HI_COMMAND_TIMEOUT); + if (status) { + hw_dbg(hw, "Host interface command failed\n"); + goto out; +@@ -647,7 +942,7 @@ static s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, + } + + out: +- hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); ++ hw->mac.ops.release_swfw_sync(hw, mask); + return status; + } + +@@ -818,15 +1113,32 @@ static s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw) + **/ + static s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 *data) + { +- s32 status = 0; ++ const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM; ++ struct ixgbe_hic_read_shadow_ram buffer; ++ s32 status; + +- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) { +- status = ixgbe_read_ee_hostif_data_X550(hw, offset, data); +- hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); +- } else { +- status = IXGBE_ERR_SWFW_SYNC; ++ buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD; ++ buffer.hdr.req.buf_lenh = 0; ++ buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN; ++ buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM; ++ ++ /* convert offset from words to bytes */ ++ buffer.address = cpu_to_be32(offset * 2); ++ /* one word */ ++ buffer.length = cpu_to_be16(sizeof(u16)); ++ ++ status = hw->mac.ops.acquire_swfw_sync(hw, mask); ++ if (status) ++ return status; ++ ++ status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer), ++ IXGBE_HI_COMMAND_TIMEOUT); ++ if (!status) { ++ *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, ++ FW_NVM_DATA_OFFSET); + } + ++ hw->mac.ops.release_swfw_sync(hw, mask); + return status; + } + +@@ -1130,47 +1442,17 @@ static s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, + return ret; + } + +-/** ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode. ++/** ++ * ixgbe_setup_ixfi_x550em_x - MAC specific iXFI configuration + * @hw: pointer to hardware structure +- * @speed: the link speed to force + * +- * Configures the integrated KR PHY to use iXFI mode. Used to connect an +- * internal and external PHY at a specific speed, without autonegotiation. ++ * iXfI configuration needed for ixgbe_mac_X550EM_x devices. + **/ +-static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed) ++static s32 ixgbe_setup_ixfi_x550em_x(struct ixgbe_hw *hw) + { + s32 status; + u32 reg_val; + +- /* Disable AN and force speed to 10G Serial. */ +- status = ixgbe_read_iosf_sb_reg_x550(hw, +- IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), +- IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); +- if (status) +- return status; +- +- reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; +- reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; +- +- /* Select forced link speed for internal PHY. */ +- switch (*speed) { +- case IXGBE_LINK_SPEED_10GB_FULL: +- reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G; +- break; +- case IXGBE_LINK_SPEED_1GB_FULL: +- reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G; +- break; +- default: +- /* Other link speeds are not supported by internal KR PHY. */ +- return IXGBE_ERR_LINK_SETUP; +- } +- +- status = ixgbe_write_iosf_sb_reg_x550(hw, +- IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), +- IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); +- if (status) +- return status; +- + /* Disable training protocol FSM. */ + status = ixgbe_read_iosf_sb_reg_x550(hw, + IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), +@@ -1230,20 +1512,111 @@ static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed) + status = ixgbe_write_iosf_sb_reg_x550(hw, + IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); +- if (status) +- return status; ++ return status; ++} + +- /* Toggle port SW reset by AN reset. */ +- status = ixgbe_read_iosf_sb_reg_x550(hw, ++/** ++ * ixgbe_restart_an_internal_phy_x550em - restart autonegotiation for the ++ * internal PHY ++ * @hw: pointer to hardware structure ++ **/ ++static s32 ixgbe_restart_an_internal_phy_x550em(struct ixgbe_hw *hw) ++{ ++ s32 status; ++ u32 link_ctrl; ++ ++ /* Restart auto-negotiation. */ ++ status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), +- IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); ++ IXGBE_SB_IOSF_TARGET_KR_PHY, &link_ctrl); ++ ++ if (status) { ++ hw_dbg(hw, "Auto-negotiation did not complete\n"); ++ return status; ++ } ++ ++ link_ctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART; ++ status = hw->mac.ops.write_iosf_sb_reg(hw, ++ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, link_ctrl); ++ ++ if (hw->mac.type == ixgbe_mac_x550em_a) { ++ u32 flx_mask_st20; ++ ++ /* Indicate to FW that AN restart has been asserted */ ++ status = hw->mac.ops.read_iosf_sb_reg(hw, ++ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_mask_st20); ++ ++ if (status) { ++ hw_dbg(hw, "Auto-negotiation did not complete\n"); ++ return status; ++ } ++ ++ flx_mask_st20 |= IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART; ++ status = hw->mac.ops.write_iosf_sb_reg(hw, ++ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, flx_mask_st20); ++ } ++ ++ return status; ++} ++ ++/** ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode. ++ * @hw: pointer to hardware structure ++ * @speed: the link speed to force ++ * ++ * Configures the integrated KR PHY to use iXFI mode. Used to connect an ++ * internal and external PHY at a specific speed, without autonegotiation. ++ **/ ++static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed) ++{ ++ struct ixgbe_mac_info *mac = &hw->mac; ++ s32 status; ++ u32 reg_val; ++ ++ /* iXFI is only supported with X552 */ ++ if (mac->type != ixgbe_mac_X550EM_x) ++ return IXGBE_ERR_LINK_SETUP; ++ ++ /* Disable AN and force speed to 10G Serial. */ ++ status = ixgbe_read_iosf_sb_reg_x550(hw, ++ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status) + return status; + +- reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART; ++ reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; ++ reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; ++ ++ /* Select forced link speed for internal PHY. */ ++ switch (*speed) { ++ case IXGBE_LINK_SPEED_10GB_FULL: ++ reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G; ++ break; ++ case IXGBE_LINK_SPEED_1GB_FULL: ++ reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G; ++ break; ++ default: ++ /* Other link speeds are not supported by internal KR PHY. */ ++ return IXGBE_ERR_LINK_SETUP; ++ } ++ + status = ixgbe_write_iosf_sb_reg_x550(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); ++ if (status) ++ return status; ++ ++ /* Additional configuration needed for x550em_x */ ++ if (hw->mac.type == ixgbe_mac_X550EM_x) { ++ status = ixgbe_setup_ixfi_x550em_x(hw); ++ if (status) ++ return status; ++ } ++ ++ /* Toggle port SW reset by AN reset. */ ++ status = ixgbe_restart_an_internal_phy_x550em(hw); + + return status; + } +@@ -1294,7 +1667,7 @@ ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw, + __always_unused bool autoneg_wait_to_complete) + { + s32 status; +- u16 slice, value; ++ u16 reg_slice, reg_val; + bool setup_linear = false; + + /* Check if SFP module is supported and linear */ +@@ -1310,71 +1683,68 @@ ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw, + if (status) + return status; + +- if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) { +- /* Configure CS4227 LINE side to 10G SR. */ +- slice = IXGBE_CS4227_LINE_SPARE22_MSB + (hw->bus.lan_id << 12); +- value = IXGBE_CS4227_SPEED_10G; +- status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227, +- slice, value); +- if (status) +- goto i2c_err; ++ /* Configure internal PHY for KR/KX. */ ++ ixgbe_setup_kr_speed_x550em(hw, speed); + +- slice = IXGBE_CS4227_LINE_SPARE24_LSB + (hw->bus.lan_id << 12); +- value = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1; +- status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227, +- slice, value); +- if (status) +- goto i2c_err; +- +- /* Configure CS4227 for HOST connection rate then type. */ +- slice = IXGBE_CS4227_HOST_SPARE22_MSB + (hw->bus.lan_id << 12); +- value = speed & IXGBE_LINK_SPEED_10GB_FULL ? +- IXGBE_CS4227_SPEED_10G : IXGBE_CS4227_SPEED_1G; +- status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227, +- slice, value); +- if (status) +- goto i2c_err; ++ /* Configure CS4227 LINE side to proper mode. */ ++ reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + (hw->bus.lan_id << 12); ++ if (setup_linear) ++ reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1; ++ else ++ reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; + +- slice = IXGBE_CS4227_HOST_SPARE24_LSB + (hw->bus.lan_id << 12); +- if (setup_linear) +- value = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 1; +- else +- value = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1; +- status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227, +- slice, value); +- if (status) +- goto i2c_err; ++ status = hw->link.ops.write_link(hw, hw->link.addr, reg_slice, ++ reg_val); + +- /* Setup XFI internal link. */ +- status = ixgbe_setup_ixfi_x550em(hw, &speed); +- if (status) { +- hw_dbg(hw, "setup_ixfi failed with %d\n", status); +- return status; +- } +- } else { +- /* Configure internal PHY for KR/KX. */ +- status = ixgbe_setup_kr_speed_x550em(hw, speed); +- if (status) { +- hw_dbg(hw, "setup_kr_speed failed with %d\n", status); +- return status; +- } ++ return status; ++} + +- /* Configure CS4227 LINE side to proper mode. */ +- slice = IXGBE_CS4227_LINE_SPARE24_LSB + (hw->bus.lan_id << 12); +- if (setup_linear) +- value = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 1; +- else +- value = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1; +- status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227, +- slice, value); +- if (status) +- goto i2c_err; ++/** ++ * ixgbe_setup_sfi_x550a - Configure the internal PHY for native SFI mode ++ * @hw: pointer to hardware structure ++ * @speed: the link speed to force ++ * ++ * Configures the integrated PHY for native SFI mode. Used to connect the ++ * internal PHY directly to an SFP cage, without autonegotiation. ++ **/ ++static s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed) ++{ ++ struct ixgbe_mac_info *mac = &hw->mac; ++ s32 status; ++ u32 reg_val; ++ ++ /* Disable all AN and force speed to 10G Serial. */ ++ status = mac->ops.read_iosf_sb_reg(hw, ++ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); ++ if (status) ++ return status; ++ ++ reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; ++ reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; ++ reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; ++ reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; ++ ++ /* Select forced link speed for internal PHY. */ ++ switch (*speed) { ++ case IXGBE_LINK_SPEED_10GB_FULL: ++ reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G; ++ break; ++ case IXGBE_LINK_SPEED_1GB_FULL: ++ reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G; ++ break; ++ default: ++ /* Other link speeds are not supported by internal PHY. */ ++ return IXGBE_ERR_LINK_SETUP; + } + +- return 0; ++ status = mac->ops.write_iosf_sb_reg(hw, ++ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); ++ ++ /* Toggle port SW reset by AN reset. */ ++ status = ixgbe_restart_an_internal_phy_x550em(hw); + +-i2c_err: +- hw_dbg(hw, "combined i2c access failed with %d\n", status); + return status; + } + +@@ -1390,45 +1760,39 @@ ixgbe_setup_mac_link_sfp_n(struct ixgbe_hw *hw, ixgbe_link_speed speed, + { + bool setup_linear = false; + u32 reg_phy_int; +- s32 rc; ++ s32 ret_val; + + /* Check if SFP module is supported and linear */ +- rc = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear); ++ ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear); + + /* If no SFP module present, then return success. Return success since + * SFP not present error is not excepted in the setup MAC link flow. + */ +- if (rc == IXGBE_ERR_SFP_NOT_PRESENT) ++ if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT) + return 0; + +- if (!rc) +- return rc; ++ if (ret_val) ++ return ret_val; + +- /* Configure internal PHY for native SFI */ +- rc = hw->mac.ops.read_iosf_sb_reg(hw, +- IXGBE_KRM_AN_CNTL_8(hw->bus.lan_id), +- IXGBE_SB_IOSF_TARGET_KR_PHY, +- ®_phy_int); +- if (rc) +- return rc; ++ /* Configure internal PHY for native SFI based on module type */ ++ ret_val = hw->mac.ops.read_iosf_sb_reg(hw, ++ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, ®_phy_int); ++ if (ret_val) ++ return ret_val; + +- if (setup_linear) { +- reg_phy_int &= ~IXGBE_KRM_AN_CNTL_8_LIMITING; +- reg_phy_int |= IXGBE_KRM_AN_CNTL_8_LINEAR; +- } else { +- reg_phy_int |= IXGBE_KRM_AN_CNTL_8_LIMITING; +- reg_phy_int &= ~IXGBE_KRM_AN_CNTL_8_LINEAR; +- } ++ reg_phy_int &= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA; ++ if (!setup_linear) ++ reg_phy_int |= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR; + +- rc = hw->mac.ops.write_iosf_sb_reg(hw, +- IXGBE_KRM_AN_CNTL_8(hw->bus.lan_id), +- IXGBE_SB_IOSF_TARGET_KR_PHY, +- reg_phy_int); +- if (rc) +- return rc; ++ ret_val = hw->mac.ops.write_iosf_sb_reg(hw, ++ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int); ++ if (ret_val) ++ return ret_val; + +- /* Setup XFI/SFI internal link */ +- return ixgbe_setup_ixfi_x550em(hw, &speed); ++ /* Setup SFI internal link. */ ++ return ixgbe_setup_sfi_x550a(hw, &speed); + } + + /** +@@ -1444,19 +1808,19 @@ ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw, ixgbe_link_speed speed, + u32 reg_slice, slice_offset; + bool setup_linear = false; + u16 reg_phy_ext; +- s32 rc; ++ s32 ret_val; + + /* Check if SFP module is supported and linear */ +- rc = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear); ++ ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear); + + /* If no SFP module present, then return success. Return success since + * SFP not present error is not excepted in the setup MAC link flow. + */ +- if (rc == IXGBE_ERR_SFP_NOT_PRESENT) ++ if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT) + return 0; + +- if (!rc) +- return rc; ++ if (ret_val) ++ return ret_val; + + /* Configure internal PHY for KR/KX. */ + ixgbe_setup_kr_speed_x550em(hw, speed); +@@ -1464,16 +1828,16 @@ ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw, ixgbe_link_speed speed, + if (hw->phy.mdio.prtad == MDIO_PRTAD_NONE) + return IXGBE_ERR_PHY_ADDR_INVALID; + +- /* Get external PHY device id */ +- rc = hw->phy.ops.read_reg(hw, IXGBE_CS4227_GLOBAL_ID_MSB, +- IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext); +- if (rc) +- return rc; ++ /* Get external PHY SKU id */ ++ ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_EFUSE_PDF_SKU, ++ IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext); ++ if (ret_val) ++ return ret_val; + + /* When configuring quad port CS4223, the MAC instance is part + * of the slice offset. + */ +- if (reg_phy_ext == IXGBE_CS4223_PHY_ID) ++ if (reg_phy_ext == IXGBE_CS4223_SKU_ID) + slice_offset = (hw->bus.lan_id + + (hw->bus.instance_id << 1)) << 12; + else +@@ -1481,12 +1845,28 @@ ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw, ixgbe_link_speed speed, + + /* Configure CS4227/CS4223 LINE side to proper mode. */ + reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + slice_offset; ++ ++ ret_val = hw->phy.ops.read_reg(hw, reg_slice, ++ IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext); ++ if (ret_val) ++ return ret_val; ++ ++ reg_phy_ext &= ~((IXGBE_CS4227_EDC_MODE_CX1 << 1) | ++ (IXGBE_CS4227_EDC_MODE_SR << 1)); ++ + if (setup_linear) + reg_phy_ext = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 1; + else + reg_phy_ext = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1; +- return hw->phy.ops.write_reg(hw, reg_slice, IXGBE_MDIO_ZERO_DEV_TYPE, +- reg_phy_ext); ++ ++ ret_val = hw->phy.ops.write_reg(hw, reg_slice, ++ IXGBE_MDIO_ZERO_DEV_TYPE, reg_phy_ext); ++ if (ret_val) ++ return ret_val; ++ ++ /* Flush previous write with a read */ ++ return hw->phy.ops.read_reg(hw, reg_slice, ++ IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext); + } + + /** +@@ -1515,8 +1895,10 @@ static s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw, + else + force_speed = IXGBE_LINK_SPEED_1GB_FULL; + +- /* If internal link mode is XFI, then setup XFI internal link. */ +- if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) { ++ /* If X552 and internal link mode is XFI, then setup XFI internal link. ++ */ ++ if (hw->mac.type == ixgbe_mac_X550EM_x && ++ !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) { + status = ixgbe_setup_ixfi_x550em(hw, &force_speed); + + if (status) +@@ -1540,7 +1922,7 @@ static s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, + bool link_up_wait_to_complete) + { + u32 status; +- u16 autoneg_status; ++ u16 i, autoneg_status; + + if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) + return IXGBE_ERR_CONFIG; +@@ -1552,14 +1934,18 @@ static s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, + if (status || !(*link_up)) + return status; + +- /* MAC link is up, so check external PHY link. +- * Read this twice back to back to indicate current status. +- */ +- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, +- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, +- &autoneg_status); +- if (status) +- return status; ++ /* MAC link is up, so check external PHY link. ++ * Link status is latching low, and can only be used to detect link ++ * drop, and not the current status of the link without performing ++ * back-to-back reads. ++ */ ++ for (i = 0; i < 2; i++) { ++ status = hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN, ++ &autoneg_status); ++ ++ if (status) ++ return status; ++ } + + /* If external PHY link is not up, then indicate link not up */ + if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS)) +@@ -1577,7 +1963,7 @@ ixgbe_setup_sgmii(struct ixgbe_hw *hw, __always_unused ixgbe_link_speed speed, + __always_unused bool autoneg_wait_to_complete) + { + struct ixgbe_mac_info *mac = &hw->mac; +- u32 lval, sval; ++ u32 lval, sval, flx_val; + s32 rc; + + rc = mac->ops.read_iosf_sb_reg(hw, +@@ -1611,12 +1997,183 @@ ixgbe_setup_sgmii(struct ixgbe_hw *hw, __always_unused ixgbe_link_speed speed, + if (rc) + return rc; + +- lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART; ++ rc = mac->ops.read_iosf_sb_reg(hw, ++ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val); ++ if (rc) ++ return rc; ++ ++ rc = mac->ops.read_iosf_sb_reg(hw, ++ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val); ++ if (rc) ++ return rc; ++ ++ flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; ++ flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G; ++ flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; ++ flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; ++ flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; ++ ++ rc = mac->ops.write_iosf_sb_reg(hw, ++ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val); ++ if (rc) ++ return rc; ++ ++ rc = ixgbe_restart_an_internal_phy_x550em(hw); ++ return rc; ++} ++ ++/** ++ * ixgbe_setup_sgmii_fw - Set up link for sgmii with firmware-controlled PHYs ++ * @hw: pointer to hardware structure ++ */ ++static s32 ixgbe_setup_sgmii_fw(struct ixgbe_hw *hw, ixgbe_link_speed speed, ++ bool autoneg_wait) ++{ ++ struct ixgbe_mac_info *mac = &hw->mac; ++ u32 lval, sval, flx_val; ++ s32 rc; ++ ++ rc = mac->ops.read_iosf_sb_reg(hw, ++ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, &lval); ++ if (rc) ++ return rc; ++ ++ lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; ++ lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; ++ lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN; ++ lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN; ++ lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G; ++ rc = mac->ops.write_iosf_sb_reg(hw, ++ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, lval); ++ if (rc) ++ return rc; ++ ++ rc = mac->ops.read_iosf_sb_reg(hw, ++ IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, &sval); ++ if (rc) ++ return rc; ++ ++ sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D; ++ sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D; ++ rc = mac->ops.write_iosf_sb_reg(hw, ++ IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, sval); ++ if (rc) ++ return rc; ++ + rc = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, lval); ++ if (rc) ++ return rc; + +- return rc; ++ rc = mac->ops.read_iosf_sb_reg(hw, ++ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val); ++ if (rc) ++ return rc; ++ ++ flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; ++ flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN; ++ flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; ++ flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; ++ flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; ++ ++ rc = mac->ops.write_iosf_sb_reg(hw, ++ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val); ++ if (rc) ++ return rc; ++ ++ ixgbe_restart_an_internal_phy_x550em(hw); ++ ++ return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait); ++} ++ ++/** ++ * ixgbe_fc_autoneg_sgmii_x550em_a - Enable flow control IEEE clause 37 ++ * @hw: pointer to hardware structure ++ * ++ * Enable flow control according to IEEE clause 37. ++ */ ++static void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw) ++{ ++ s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED; ++ u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 }; ++ ixgbe_link_speed speed; ++ bool link_up; ++ ++ /* AN should have completed when the cable was plugged in. ++ * Look for reasons to bail out. Bail out if: ++ * - FC autoneg is disabled, or if ++ * - link is not up. ++ */ ++ if (hw->fc.disable_fc_autoneg) ++ goto out; ++ ++ hw->mac.ops.check_link(hw, &speed, &link_up, false); ++ if (!link_up) ++ goto out; ++ ++ /* Check if auto-negotiation has completed */ ++ status = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &info); ++ if (status || !(info[0] & FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE)) { ++ status = IXGBE_ERR_FC_NOT_NEGOTIATED; ++ goto out; ++ } ++ ++ /* Negotiate the flow control */ ++ status = ixgbe_negotiate_fc(hw, info[0], info[0], ++ FW_PHY_ACT_GET_LINK_INFO_FC_RX, ++ FW_PHY_ACT_GET_LINK_INFO_FC_TX, ++ FW_PHY_ACT_GET_LINK_INFO_LP_FC_RX, ++ FW_PHY_ACT_GET_LINK_INFO_LP_FC_TX); ++ ++out: ++ if (!status) { ++ hw->fc.fc_was_autonegged = true; ++ } else { ++ hw->fc.fc_was_autonegged = false; ++ hw->fc.current_mode = hw->fc.requested_mode; ++ } ++} ++ ++/** ixgbe_init_mac_link_ops_X550em_a - Init mac link function pointers ++ * @hw: pointer to hardware structure ++ **/ ++static void ixgbe_init_mac_link_ops_X550em_a(struct ixgbe_hw *hw) ++{ ++ struct ixgbe_mac_info *mac = &hw->mac; ++ ++ switch (mac->ops.get_media_type(hw)) { ++ case ixgbe_media_type_fiber: ++ mac->ops.setup_fc = NULL; ++ mac->ops.fc_autoneg = ixgbe_fc_autoneg_fiber_x550em_a; ++ break; ++ case ixgbe_media_type_copper: ++ if (hw->device_id != IXGBE_DEV_ID_X550EM_A_1G_T && ++ hw->device_id != IXGBE_DEV_ID_X550EM_A_1G_T_L) { ++ mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em; ++ break; ++ } ++ mac->ops.fc_autoneg = ixgbe_fc_autoneg_sgmii_x550em_a; ++ mac->ops.setup_fc = ixgbe_fc_autoneg_fw; ++ mac->ops.setup_link = ixgbe_setup_sgmii_fw; ++ mac->ops.check_link = ixgbe_check_mac_link_generic; ++ break; ++ case ixgbe_media_type_backplane: ++ mac->ops.fc_autoneg = ixgbe_fc_autoneg_backplane_x550em_a; ++ mac->ops.setup_fc = ixgbe_setup_fc_backplane_x550em_a; ++ break; ++ default: ++ break; ++ } + } + + /** ixgbe_init_mac_link_ops_X550em - init mac link function pointers +@@ -1654,10 +2211,12 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw) + ixgbe_set_soft_rate_select_speed; + break; + case ixgbe_media_type_copper: ++ if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T) ++ break; + mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em; + mac->ops.setup_fc = ixgbe_setup_fc_generic; + mac->ops.check_link = ixgbe_check_link_t_X550em; +- return; ++ break; + case ixgbe_media_type_backplane: + if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII || + hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L) +@@ -1666,6 +2225,10 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw) + default: + break; + } ++ ++ /* Additional modification for X550em_a devices */ ++ if (hw->mac.type == ixgbe_mac_x550em_a) ++ ixgbe_init_mac_link_ops_X550em_a(hw); + } + + /** ixgbe_setup_sfp_modules_X550em - Setup SFP module +@@ -1696,6 +2259,12 @@ static s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg) + { ++ if (hw->phy.type == ixgbe_phy_fw) { ++ *autoneg = true; ++ *speed = hw->phy.speeds_supported; ++ return 0; ++ } ++ + /* SFP */ + if (hw->phy.media_type == ixgbe_media_type_fiber) { + /* CS4227 SFP must not enable auto-negotiation */ +@@ -1714,8 +2283,39 @@ static s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw, + else + *speed = IXGBE_LINK_SPEED_10GB_FULL; + } else { +- *speed = IXGBE_LINK_SPEED_10GB_FULL | +- IXGBE_LINK_SPEED_1GB_FULL; ++ switch (hw->phy.type) { ++ case ixgbe_phy_x550em_kx4: ++ *speed = IXGBE_LINK_SPEED_1GB_FULL | ++ IXGBE_LINK_SPEED_2_5GB_FULL | ++ IXGBE_LINK_SPEED_10GB_FULL; ++ break; ++ case ixgbe_phy_x550em_xfi: ++ *speed = IXGBE_LINK_SPEED_1GB_FULL | ++ IXGBE_LINK_SPEED_10GB_FULL; ++ break; ++ case ixgbe_phy_ext_1g_t: ++ case ixgbe_phy_sgmii: ++ *speed = IXGBE_LINK_SPEED_1GB_FULL; ++ break; ++ case ixgbe_phy_x550em_kr: ++ if (hw->mac.type == ixgbe_mac_x550em_a) { ++ /* check different backplane modes */ ++ if (hw->phy.nw_mng_if_sel & ++ IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) { ++ *speed = IXGBE_LINK_SPEED_2_5GB_FULL; ++ break; ++ } else if (hw->device_id == ++ IXGBE_DEV_ID_X550EM_A_KR_L) { ++ *speed = IXGBE_LINK_SPEED_1GB_FULL; ++ break; ++ } ++ } ++ /* fall through */ ++ default: ++ *speed = IXGBE_LINK_SPEED_10GB_FULL | ++ IXGBE_LINK_SPEED_1GB_FULL; ++ break; ++ } + *autoneg = true; + } + return 0; +@@ -1742,7 +2342,7 @@ static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc) + + /* Vendor alarm triggered */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, ++ MDIO_MMD_VEND1, + ®); + + if (status || !(reg & IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN)) +@@ -1750,7 +2350,7 @@ static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc) + + /* Vendor Auto-Neg alarm triggered or Global alarm 1 triggered */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, ++ MDIO_MMD_VEND1, + ®); + + if (status || !(reg & (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN | +@@ -1759,7 +2359,7 @@ static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc) + + /* Global alarm triggered */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, ++ MDIO_MMD_VEND1, + ®); + + if (status) +@@ -1774,7 +2374,7 @@ static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc) + if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) { + /* device fault alarm triggered */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, ++ MDIO_MMD_VEND1, + ®); + if (status) + return status; +@@ -1789,14 +2389,14 @@ static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc) + + /* Vendor alarm 2 triggered */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG, +- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®); ++ MDIO_MMD_AN, ®); + + if (status || !(reg & IXGBE_MDIO_GLOBAL_STD_ALM2_INT)) + return status; + + /* link connect/disconnect event occurred */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2, +- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®); ++ MDIO_MMD_AN, ®); + + if (status) + return status; +@@ -1827,21 +2427,34 @@ static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw) + status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc); + + /* Enable link status change alarm */ +- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK, +- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®); +- if (status) +- return status; + +- reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN; ++ /* Enable the LASI interrupts on X552 devices to receive notifications ++ * of the link configurations of the external PHY and correspondingly ++ * support the configuration of the internal iXFI link, since iXFI does ++ * not support auto-negotiation. This is not required for X553 devices ++ * having KR support, which performs auto-negotiations and which is used ++ * as the internal link to the external PHY. Hence adding a check here ++ * to avoid enabling LASI interrupts for X553 devices. ++ */ ++ if (hw->mac.type != ixgbe_mac_x550em_a) { ++ status = hw->phy.ops.read_reg(hw, ++ IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK, ++ MDIO_MMD_AN, ®); ++ if (status) ++ return status; + +- status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK, +- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg); +- if (status) +- return status; ++ reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN; ++ ++ status = hw->phy.ops.write_reg(hw, ++ IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK, ++ MDIO_MMD_AN, reg); ++ if (status) ++ return status; ++ } + + /* Enable high temperature failure and global fault alarms */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, ++ MDIO_MMD_VEND1, + ®); + if (status) + return status; +@@ -1850,14 +2463,14 @@ static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw) + IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN); + + status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, ++ MDIO_MMD_VEND1, + reg); + if (status) + return status; + + /* Enable vendor Auto-Neg alarm and Global Interrupt Mask 1 alarm */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, ++ MDIO_MMD_VEND1, + ®); + if (status) + return status; +@@ -1866,14 +2479,14 @@ static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw) + IXGBE_MDIO_GLOBAL_ALARM_1_INT); + + status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, ++ MDIO_MMD_VEND1, + reg); + if (status) + return status; + + /* Enable chip-wide vendor alarm */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, ++ MDIO_MMD_VEND1, + ®); + if (status) + return status; +@@ -1881,7 +2494,7 @@ static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw) + reg |= IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN; + + status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, ++ MDIO_MMD_VEND1, + reg); + + return status; +@@ -1945,51 +2558,31 @@ static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw, + if (speed & IXGBE_LINK_SPEED_1GB_FULL) + reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX; + +- /* Restart auto-negotiation. */ +- reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART; + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + +- return status; +-} +- +-/** ixgbe_setup_kx4_x550em - Configure the KX4 PHY. +- * @hw: pointer to hardware structure +- * +- * Configures the integrated KX4 PHY. +- **/ +-static s32 ixgbe_setup_kx4_x550em(struct ixgbe_hw *hw) +-{ +- s32 status; +- u32 reg_val; +- +- status = hw->mac.ops.read_iosf_sb_reg(hw, IXGBE_KX4_LINK_CNTL_1, +- IXGBE_SB_IOSF_TARGET_KX4_PCS0 + +- hw->bus.lan_id, ®_val); +- if (status) +- return status; +- +- reg_val &= ~(IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX4 | +- IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX); +- +- reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_ENABLE; ++ if (hw->mac.type == ixgbe_mac_x550em_a) { ++ /* Set lane mode to KR auto negotiation */ ++ status = hw->mac.ops.read_iosf_sb_reg(hw, ++ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + +- /* Advertise 10G support. */ +- if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) +- reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX4; ++ if (status) ++ return status; + +- /* Advertise 1G support. */ +- if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) +- reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX; ++ reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; ++ reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN; ++ reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; ++ reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; ++ reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; + +- /* Restart auto-negotiation. */ +- reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_RESTART; +- status = hw->mac.ops.write_iosf_sb_reg(hw, IXGBE_KX4_LINK_CNTL_1, +- IXGBE_SB_IOSF_TARGET_KX4_PCS0 + +- hw->bus.lan_id, reg_val); ++ status = hw->mac.ops.write_iosf_sb_reg(hw, ++ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); ++ } + +- return status; ++ return ixgbe_restart_an_internal_phy_x550em(hw); + } + + /** +@@ -2002,6 +2595,9 @@ static s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw) + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL) + return 0; + ++ if (ixgbe_check_reset_blocked(hw)) ++ return 0; ++ + return ixgbe_setup_kr_speed_x550em(hw, hw->phy.autoneg_advertised); + } + +@@ -2019,14 +2615,12 @@ static s32 ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up) + *link_up = false; + + /* read this twice back to back to indicate current status */ +- ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, +- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ++ ret = hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN, + &autoneg_status); + if (ret) + return ret; + +- ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, +- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ++ ret = hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN, + &autoneg_status); + if (ret) + return ret; +@@ -2057,7 +2651,8 @@ static s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw) + if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) + return IXGBE_ERR_CONFIG; + +- if (hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE) { ++ if (!(hw->mac.type == ixgbe_mac_X550EM_x && ++ !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE))) { + speed = IXGBE_LINK_SPEED_10GB_FULL | + IXGBE_LINK_SPEED_1GB_FULL; + return ixgbe_setup_kr_speed_x550em(hw, speed); +@@ -2072,7 +2667,7 @@ static s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw) + return 0; + + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT, +- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ++ MDIO_MMD_AN, + &speed); + if (status) + return status; +@@ -2133,10 +2728,10 @@ static s32 ixgbe_led_on_t_x550em(struct ixgbe_hw *hw, u32 led_idx) + + /* To turn on the LED, set mode to ON. */ + hw->phy.ops.read_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data); ++ MDIO_MMD_VEND1, &phy_data); + phy_data |= IXGBE_X557_LED_MANUAL_SET_MASK; + hw->phy.ops.write_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data); ++ MDIO_MMD_VEND1, phy_data); + + return 0; + } +@@ -2155,14 +2750,70 @@ static s32 ixgbe_led_off_t_x550em(struct ixgbe_hw *hw, u32 led_idx) + + /* To turn on the LED, set mode to ON. */ + hw->phy.ops.read_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data); ++ MDIO_MMD_VEND1, &phy_data); + phy_data &= ~IXGBE_X557_LED_MANUAL_SET_MASK; + hw->phy.ops.write_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data); ++ MDIO_MMD_VEND1, phy_data); + + return 0; + } + ++/** ++ * ixgbe_set_fw_drv_ver_x550 - Sends driver version to firmware ++ * @hw: pointer to the HW structure ++ * @maj: driver version major number ++ * @min: driver version minor number ++ * @build: driver version build number ++ * @sub: driver version sub build number ++ * @len: length of driver_ver string ++ * @driver_ver: driver string ++ * ++ * Sends driver version number to firmware through the manageability ++ * block. On success return 0 ++ * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring ++ * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. ++ **/ ++static s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min, ++ u8 build, u8 sub, u16 len, ++ const char *driver_ver) ++{ ++ struct ixgbe_hic_drv_info2 fw_cmd; ++ s32 ret_val; ++ int i; ++ ++ if (!len || !driver_ver || (len > sizeof(fw_cmd.driver_string))) ++ return IXGBE_ERR_INVALID_ARGUMENT; ++ ++ fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO; ++ fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN + len; ++ fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; ++ fw_cmd.port_num = (u8)hw->bus.func; ++ fw_cmd.ver_maj = maj; ++ fw_cmd.ver_min = min; ++ fw_cmd.ver_build = build; ++ fw_cmd.ver_sub = sub; ++ fw_cmd.hdr.checksum = 0; ++ memcpy(fw_cmd.driver_string, driver_ver, len); ++ fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd, ++ (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len)); ++ ++ for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) { ++ ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd, ++ sizeof(fw_cmd), ++ IXGBE_HI_COMMAND_TIMEOUT, ++ true); ++ if (ret_val) ++ continue; ++ ++ if (fw_cmd.hdr.cmd_or_resp.ret_status != ++ FW_CEM_RESP_STATUS_SUCCESS) ++ return IXGBE_ERR_HOST_INTERFACE_COMMAND; ++ return 0; ++ } ++ ++ return ret_val; ++} ++ + /** ixgbe_get_lcd_x550em - Determine lowest common denominator + * @hw: pointer to hardware structure + * @lcd_speed: pointer to lowest common link speed +@@ -2179,7 +2830,7 @@ static s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, + *lcd_speed = IXGBE_LINK_SPEED_UNKNOWN; + + status = hw->phy.ops.read_reg(hw, IXGBE_AUTO_NEG_LP_STATUS, +- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ++ MDIO_MMD_AN, + &an_lp_status); + if (status) + return status; +@@ -2208,7 +2859,7 @@ static s32 ixgbe_setup_fc_x550em(struct ixgbe_hw *hw) + { + bool pause, asm_dir; + u32 reg_val; +- s32 rc; ++ s32 rc = 0; + + /* Validate the requested mode */ + if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { +@@ -2251,33 +2902,122 @@ static s32 ixgbe_setup_fc_x550em(struct ixgbe_hw *hw) + return IXGBE_ERR_CONFIG; + } + +- if (hw->device_id != IXGBE_DEV_ID_X550EM_X_KR && +- hw->device_id != IXGBE_DEV_ID_X550EM_A_KR && +- hw->device_id != IXGBE_DEV_ID_X550EM_A_KR_L) +- return 0; ++ switch (hw->device_id) { ++ case IXGBE_DEV_ID_X550EM_X_KR: ++ case IXGBE_DEV_ID_X550EM_A_KR: ++ case IXGBE_DEV_ID_X550EM_A_KR_L: ++ rc = hw->mac.ops.read_iosf_sb_reg(hw, ++ IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, ++ ®_val); ++ if (rc) ++ return rc; ++ ++ reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE | ++ IXGBE_KRM_AN_CNTL_1_ASM_PAUSE); ++ if (pause) ++ reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE; ++ if (asm_dir) ++ reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE; ++ rc = hw->mac.ops.write_iosf_sb_reg(hw, ++ IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, ++ reg_val); ++ ++ /* This device does not fully support AN. */ ++ hw->fc.disable_fc_autoneg = true; ++ break; ++ case IXGBE_DEV_ID_X550EM_X_XFI: ++ hw->fc.disable_fc_autoneg = true; ++ break; ++ default: ++ break; ++ } ++ return rc; ++} + +- rc = hw->mac.ops.read_iosf_sb_reg(hw, +- IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), +- IXGBE_SB_IOSF_TARGET_KR_PHY, +- ®_val); +- if (rc) +- return rc; ++/** ++ * ixgbe_fc_autoneg_backplane_x550em_a - Enable flow control IEEE clause 37 ++ * @hw: pointer to hardware structure ++ **/ ++static void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw) ++{ ++ u32 link_s1, lp_an_page_low, an_cntl_1; ++ s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED; ++ ixgbe_link_speed speed; ++ bool link_up; + +- reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE | +- IXGBE_KRM_AN_CNTL_1_ASM_PAUSE); +- if (pause) +- reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE; +- if (asm_dir) +- reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE; +- rc = hw->mac.ops.write_iosf_sb_reg(hw, +- IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), +- IXGBE_SB_IOSF_TARGET_KR_PHY, +- reg_val); ++ /* AN should have completed when the cable was plugged in. ++ * Look for reasons to bail out. Bail out if: ++ * - FC autoneg is disabled, or if ++ * - link is not up. ++ */ ++ if (hw->fc.disable_fc_autoneg) { ++ hw_err(hw, "Flow control autoneg is disabled"); ++ goto out; ++ } + +- /* This device does not fully support AN. */ +- hw->fc.disable_fc_autoneg = true; ++ hw->mac.ops.check_link(hw, &speed, &link_up, false); ++ if (!link_up) { ++ hw_err(hw, "The link is down"); ++ goto out; ++ } + +- return rc; ++ /* Check at auto-negotiation has completed */ ++ status = hw->mac.ops.read_iosf_sb_reg(hw, ++ IXGBE_KRM_LINK_S1(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, &link_s1); ++ ++ if (status || (link_s1 & IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE) == 0) { ++ hw_dbg(hw, "Auto-Negotiation did not complete\n"); ++ status = IXGBE_ERR_FC_NOT_NEGOTIATED; ++ goto out; ++ } ++ ++ /* Read the 10g AN autoc and LP ability registers and resolve ++ * local flow control settings accordingly ++ */ ++ status = hw->mac.ops.read_iosf_sb_reg(hw, ++ IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl_1); ++ ++ if (status) { ++ hw_dbg(hw, "Auto-Negotiation did not complete\n"); ++ goto out; ++ } ++ ++ status = hw->mac.ops.read_iosf_sb_reg(hw, ++ IXGBE_KRM_LP_BASE_PAGE_HIGH(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, &lp_an_page_low); ++ ++ if (status) { ++ hw_dbg(hw, "Auto-Negotiation did not complete\n"); ++ goto out; ++ } ++ ++ status = ixgbe_negotiate_fc(hw, an_cntl_1, lp_an_page_low, ++ IXGBE_KRM_AN_CNTL_1_SYM_PAUSE, ++ IXGBE_KRM_AN_CNTL_1_ASM_PAUSE, ++ IXGBE_KRM_LP_BASE_PAGE_HIGH_SYM_PAUSE, ++ IXGBE_KRM_LP_BASE_PAGE_HIGH_ASM_PAUSE); ++ ++out: ++ if (!status) { ++ hw->fc.fc_was_autonegged = true; ++ } else { ++ hw->fc.fc_was_autonegged = false; ++ hw->fc.current_mode = hw->fc.requested_mode; ++ } ++} ++ ++/** ++ * ixgbe_fc_autoneg_fiber_x550em_a - passthrough FC settings ++ * @hw: pointer to hardware structure ++ **/ ++static void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *hw) ++{ ++ hw->fc.fc_was_autonegged = false; ++ hw->fc.current_mode = hw->fc.requested_mode; + } + + /** ixgbe_enter_lplu_x550em - Transition to low power states +@@ -2326,7 +3066,7 @@ static s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw) + return ixgbe_set_copper_phy_power(hw, false); + + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT, +- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ++ MDIO_MMD_AN, + &speed); + if (status) + return status; +@@ -2348,20 +3088,20 @@ static s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw) + + /* Clear AN completed indication */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM, +- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ++ MDIO_MMD_AN, + &autoneg_reg); + if (status) + return status; + +- status = hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, +- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ++ status = hw->phy.ops.read_reg(hw, MDIO_AN_10GBT_CTRL, ++ MDIO_MMD_AN, + &an_10g_cntl_reg); + if (status) + return status; + + status = hw->phy.ops.read_reg(hw, + IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, +- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ++ MDIO_MMD_AN, + &autoneg_reg); + if (status) + return status; +@@ -2378,6 +3118,50 @@ static s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw) + } + + /** ++ * ixgbe_reset_phy_fw - Reset firmware-controlled PHYs ++ * @hw: pointer to hardware structure ++ */ ++static s32 ixgbe_reset_phy_fw(struct ixgbe_hw *hw) ++{ ++ u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 }; ++ s32 rc; ++ ++ if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw)) ++ return 0; ++ ++ rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_PHY_SW_RESET, &store); ++ if (rc) ++ return rc; ++ memset(store, 0, sizeof(store)); ++ ++ rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_INIT_PHY, &store); ++ if (rc) ++ return rc; ++ ++ return ixgbe_setup_fw_link(hw); ++} ++ ++/** ++ * ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp ++ * @hw: pointer to hardware structure ++ */ ++static s32 ixgbe_check_overtemp_fw(struct ixgbe_hw *hw) ++{ ++ u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 }; ++ s32 rc; ++ ++ rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store); ++ if (rc) ++ return rc; ++ ++ if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) { ++ ixgbe_shutdown_fw_phy(hw); ++ return IXGBE_ERR_OVERTEMP; ++ } ++ return 0; ++} ++ ++/** + * ixgbe_read_mng_if_sel_x550em - Read NW_MNG_IF_SEL register + * @hw: pointer to hardware structure + * +@@ -2398,6 +3182,18 @@ static void ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw) + hw->phy.mdio.prtad = (hw->phy.nw_mng_if_sel & + IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >> + IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT; ++#if 1 /* Since by Intel FW(LEK8),LAN controller 1 default set port 0 use phy address 0 ++ * and port 1 use phy address 1, we swap it for Porsche2 platform. ++ * By hilbert. ++ */ ++ if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) { ++ /*hw_err(hw, "####swap phy address used for different lan id in LAN conroller-1\n");*/ ++ hw->phy.mdio.prtad = (hw->bus.lan_id == 0) ? (1) : (0); ++ /*hw_err(hw, "####lan id: %d, phy address:%d\n", ++ hw->bus.lan_id, ++ hw->phy.mdio.prtad);*/ ++ } ++#endif + } + } + +@@ -2433,7 +3229,7 @@ static s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw) + /* Set functions pointers based on phy type */ + switch (hw->phy.type) { + case ixgbe_phy_x550em_kx4: +- phy->ops.setup_link = ixgbe_setup_kx4_x550em; ++ phy->ops.setup_link = NULL; + phy->ops.read_reg = ixgbe_read_phy_reg_x550em; + phy->ops.write_reg = ixgbe_write_phy_reg_x550em; + break; +@@ -2442,6 +3238,12 @@ static s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw) + phy->ops.read_reg = ixgbe_read_phy_reg_x550em; + phy->ops.write_reg = ixgbe_write_phy_reg_x550em; + break; ++ case ixgbe_phy_x550em_xfi: ++ /* link is managed by HW */ ++ phy->ops.setup_link = NULL; ++ phy->ops.read_reg = ixgbe_read_phy_reg_x550em; ++ phy->ops.write_reg = ixgbe_write_phy_reg_x550em; ++ break; + case ixgbe_phy_x550em_ext_t: + /* Save NW management interface connected on board. This is used + * to determine internal PHY mode +@@ -2463,6 +3265,19 @@ static s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw) + phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em; + phy->ops.reset = ixgbe_reset_phy_t_X550em; + break; ++ case ixgbe_phy_sgmii: ++ phy->ops.setup_link = NULL; ++ break; ++ case ixgbe_phy_fw: ++ phy->ops.setup_link = ixgbe_setup_fw_link; ++ phy->ops.reset = ixgbe_reset_phy_fw; ++ break; ++ case ixgbe_phy_ext_1g_t: ++ phy->ops.setup_link = NULL; ++ phy->ops.read_reg = NULL; ++ phy->ops.write_reg = NULL; ++ phy->ops.reset = NULL; ++ break; + default: + break; + } +@@ -2488,6 +3303,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw) + /* Fallthrough */ + case IXGBE_DEV_ID_X550EM_X_KR: + case IXGBE_DEV_ID_X550EM_X_KX4: ++ case IXGBE_DEV_ID_X550EM_X_XFI: + case IXGBE_DEV_ID_X550EM_A_KR: + case IXGBE_DEV_ID_X550EM_A_KR_L: + media_type = ixgbe_media_type_backplane; +@@ -2500,6 +3316,8 @@ static enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw) + case IXGBE_DEV_ID_X550EM_X_1G_T: + case IXGBE_DEV_ID_X550EM_X_10G_T: + case IXGBE_DEV_ID_X550EM_A_10G_T: ++ case IXGBE_DEV_ID_X550EM_A_1G_T: ++ case IXGBE_DEV_ID_X550EM_A_1G_T_L: + media_type = ixgbe_media_type_copper; + break; + default: +@@ -2519,7 +3337,7 @@ static s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw) + + status = hw->phy.ops.read_reg(hw, + IXGBE_MDIO_TX_VENDOR_ALARMS_3, +- IXGBE_MDIO_PMA_PMD_DEV_TYPE, ++ MDIO_MMD_PMAPMD, + ®); + if (status) + return status; +@@ -2530,7 +3348,7 @@ static s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw) + if (reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) { + status = hw->phy.ops.read_reg(hw, + IXGBE_MDIO_GLOBAL_RES_PR_10, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, ++ MDIO_MMD_VEND1, + ®); + if (status) + return status; +@@ -2539,7 +3357,7 @@ static s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw) + + status = hw->phy.ops.write_reg(hw, + IXGBE_MDIO_GLOBAL_RES_PR_10, +- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, ++ MDIO_MMD_VEND1, + reg); + if (status) + return status; +@@ -2567,6 +3385,13 @@ static void ixgbe_set_mdio_speed(struct ixgbe_hw *hw) + hlreg0 &= ~IXGBE_HLREG0_MDCSPD; + IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); + break; ++ case IXGBE_DEV_ID_X550EM_A_1G_T: ++ case IXGBE_DEV_ID_X550EM_A_1G_T_L: ++ /* Select fast MDIO clock speed for these devices */ ++ hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); ++ hlreg0 |= IXGBE_HLREG0_MDCSPD; ++ IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); ++ break; + default: + break; + } +@@ -2586,6 +3411,7 @@ static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) + u32 ctrl = 0; + u32 i; + bool link_up = false; ++ u32 swfw_mask = hw->phy.phy_semaphore_mask; + + /* Call adapter stop to disable Tx/Rx and clear interrupts */ + status = hw->mac.ops.stop_adapter(hw); +@@ -2613,6 +3439,9 @@ static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) + hw->phy.sfp_setup_needed = false; + } + ++ if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) ++ return status; ++ + /* Reset PHY */ + if (!hw->phy.reset_disable && hw->phy.ops.reset) + hw->phy.ops.reset(hw); +@@ -2631,9 +3460,16 @@ static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) + ctrl = IXGBE_CTRL_RST; + } + ++ status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); ++ if (status) { ++ hw_dbg(hw, "semaphore failed with %d", status); ++ return IXGBE_ERR_SWFW_SYNC; ++ } ++ + ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); + IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); + IXGBE_WRITE_FLUSH(hw); ++ hw->mac.ops.release_swfw_sync(hw, swfw_mask); + usleep_range(1000, 1200); + + /* Poll for reset bit to self-clear meaning reset is complete */ +@@ -2728,6 +3564,90 @@ static void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, + } + + /** ++ * ixgbe_setup_fc_backplane_x550em_a - Set up flow control ++ * @hw: pointer to hardware structure ++ * ++ * Called at init time to set up flow control. ++ **/ ++static s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw) ++{ ++ s32 status = 0; ++ u32 an_cntl = 0; ++ ++ /* Validate the requested mode */ ++ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { ++ hw_err(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); ++ return IXGBE_ERR_INVALID_LINK_SETTINGS; ++ } ++ ++ if (hw->fc.requested_mode == ixgbe_fc_default) ++ hw->fc.requested_mode = ixgbe_fc_full; ++ ++ /* Set up the 1G and 10G flow control advertisement registers so the ++ * HW will be able to do FC autoneg once the cable is plugged in. If ++ * we link at 10G, the 1G advertisement is harmless and vice versa. ++ */ ++ status = hw->mac.ops.read_iosf_sb_reg(hw, ++ IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl); ++ ++ if (status) { ++ hw_dbg(hw, "Auto-Negotiation did not complete\n"); ++ return status; ++ } ++ ++ /* The possible values of fc.requested_mode are: ++ * 0: Flow control is completely disabled ++ * 1: Rx flow control is enabled (we can receive pause frames, ++ * but not send pause frames). ++ * 2: Tx flow control is enabled (we can send pause frames but ++ * we do not support receiving pause frames). ++ * 3: Both Rx and Tx flow control (symmetric) are enabled. ++ * other: Invalid. ++ */ ++ switch (hw->fc.requested_mode) { ++ case ixgbe_fc_none: ++ /* Flow control completely disabled by software override. */ ++ an_cntl &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE | ++ IXGBE_KRM_AN_CNTL_1_ASM_PAUSE); ++ break; ++ case ixgbe_fc_tx_pause: ++ /* Tx Flow control is enabled, and Rx Flow control is ++ * disabled by software override. ++ */ ++ an_cntl |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE; ++ an_cntl &= ~IXGBE_KRM_AN_CNTL_1_SYM_PAUSE; ++ break; ++ case ixgbe_fc_rx_pause: ++ /* Rx Flow control is enabled and Tx Flow control is ++ * disabled by software override. Since there really ++ * isn't a way to advertise that we are capable of RX ++ * Pause ONLY, we will advertise that we support both ++ * symmetric and asymmetric Rx PAUSE, as such we fall ++ * through to the fc_full statement. Later, we will ++ * disable the adapter's ability to send PAUSE frames. ++ */ ++ case ixgbe_fc_full: ++ /* Flow control (both Rx and Tx) is enabled by SW override. */ ++ an_cntl |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE | ++ IXGBE_KRM_AN_CNTL_1_ASM_PAUSE; ++ break; ++ default: ++ hw_err(hw, "Flow control param set incorrectly\n"); ++ return IXGBE_ERR_CONFIG; ++ } ++ ++ status = hw->mac.ops.write_iosf_sb_reg(hw, ++ IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), ++ IXGBE_SB_IOSF_TARGET_KR_PHY, an_cntl); ++ ++ /* Restart auto-negotiation. */ ++ status = ixgbe_restart_an_internal_phy_x550em(hw); ++ ++ return status; ++} ++ ++/** + * ixgbe_set_mux - Set mux for port 1 access with CS4227 + * @hw: pointer to hardware structure + * @state: set mux if 1, clear if 0 +@@ -2881,7 +3801,13 @@ static s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + if (hw->mac.ops.acquire_swfw_sync(hw, mask)) + return IXGBE_ERR_SWFW_SYNC; + ++#if 0 /* To use C22 MDI access function created by our own. ++ * By hilbert ++ */ + status = ixgbe_write_phy_reg_mdi(hw, reg_addr, device_type, phy_data); ++#else ++ status = hw->phy.ops.write_reg_mdi(hw, reg_addr, device_type, phy_data); ++#endif + hw->mac.ops.release_swfw_sync(hw, mask); + + return status; +@@ -2914,7 +3840,7 @@ static s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + .clear_vfta = &ixgbe_clear_vfta_generic, \ + .set_vfta = &ixgbe_set_vfta_generic, \ + .fc_enable = &ixgbe_fc_enable_generic, \ +- .set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic, \ ++ .set_fw_drv_ver = &ixgbe_set_fw_drv_ver_x550, \ + .init_uta_tables = &ixgbe_init_uta_tables_generic, \ + .set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing, \ + .set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing, \ +@@ -2933,6 +3859,7 @@ static const struct ixgbe_mac_operations mac_ops_X550 = { + X550_COMMON_MAC + .led_on = ixgbe_led_on_generic, + .led_off = ixgbe_led_off_generic, ++ .init_led_link_act = ixgbe_init_led_link_act_generic, + .reset_hw = &ixgbe_reset_hw_X540, + .get_media_type = &ixgbe_get_media_type_X540, + .get_san_mac_addr = &ixgbe_get_san_mac_addr_generic, +@@ -2947,12 +3874,14 @@ static const struct ixgbe_mac_operations mac_ops_X550 = { + .prot_autoc_read = prot_autoc_read_generic, + .prot_autoc_write = prot_autoc_write_generic, + .setup_fc = ixgbe_setup_fc_generic, ++ .fc_autoneg = ixgbe_fc_autoneg, + }; + + static const struct ixgbe_mac_operations mac_ops_X550EM_x = { + X550_COMMON_MAC + .led_on = ixgbe_led_on_t_x550em, + .led_off = ixgbe_led_off_t_x550em, ++ .init_led_link_act = ixgbe_init_led_link_act_generic, + .reset_hw = &ixgbe_reset_hw_X550em, + .get_media_type = &ixgbe_get_media_type_X550em, + .get_san_mac_addr = NULL, +@@ -2965,6 +3894,29 @@ static const struct ixgbe_mac_operations mac_ops_X550EM_x = { + .release_swfw_sync = &ixgbe_release_swfw_sync_X550em, + .init_swfw_sync = &ixgbe_init_swfw_sync_X540, + .setup_fc = NULL, /* defined later */ ++ .fc_autoneg = ixgbe_fc_autoneg, ++ .read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550, ++ .write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550, ++}; ++ ++static const struct ixgbe_mac_operations mac_ops_X550EM_x_fw = { ++ X550_COMMON_MAC ++ .led_on = NULL, ++ .led_off = NULL, ++ .init_led_link_act = NULL, ++ .reset_hw = &ixgbe_reset_hw_X550em, ++ .get_media_type = &ixgbe_get_media_type_X550em, ++ .get_san_mac_addr = NULL, ++ .get_wwn_prefix = NULL, ++ .setup_link = &ixgbe_setup_mac_link_X540, ++ .get_link_capabilities = &ixgbe_get_link_capabilities_X550em, ++ .get_bus_info = &ixgbe_get_bus_info_X550em, ++ .setup_sfp = ixgbe_setup_sfp_modules_X550em, ++ .acquire_swfw_sync = &ixgbe_acquire_swfw_sync_X550em, ++ .release_swfw_sync = &ixgbe_release_swfw_sync_X550em, ++ .init_swfw_sync = &ixgbe_init_swfw_sync_X540, ++ .setup_fc = NULL, ++ .fc_autoneg = ixgbe_fc_autoneg, + .read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550, + .write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550, + }; +@@ -2973,6 +3925,28 @@ static struct ixgbe_mac_operations mac_ops_x550em_a = { + X550_COMMON_MAC + .led_on = ixgbe_led_on_t_x550em, + .led_off = ixgbe_led_off_t_x550em, ++ .init_led_link_act = ixgbe_init_led_link_act_generic, ++ .reset_hw = ixgbe_reset_hw_X550em, ++ .get_media_type = ixgbe_get_media_type_X550em, ++ .get_san_mac_addr = NULL, ++ .get_wwn_prefix = NULL, ++ .setup_link = &ixgbe_setup_mac_link_X540, ++ .get_link_capabilities = ixgbe_get_link_capabilities_X550em, ++ .get_bus_info = ixgbe_get_bus_info_X550em, ++ .setup_sfp = ixgbe_setup_sfp_modules_X550em, ++ .acquire_swfw_sync = ixgbe_acquire_swfw_sync_x550em_a, ++ .release_swfw_sync = ixgbe_release_swfw_sync_x550em_a, ++ .setup_fc = ixgbe_setup_fc_x550em, ++ .fc_autoneg = ixgbe_fc_autoneg, ++ .read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550a, ++ .write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550a, ++}; ++ ++static struct ixgbe_mac_operations mac_ops_x550em_a_fw = { ++ X550_COMMON_MAC ++ .led_on = ixgbe_led_on_generic, ++ .led_off = ixgbe_led_off_generic, ++ .init_led_link_act = ixgbe_init_led_link_act_generic, + .reset_hw = ixgbe_reset_hw_X550em, + .get_media_type = ixgbe_get_media_type_X550em, + .get_san_mac_addr = NULL, +@@ -2984,6 +3958,7 @@ static struct ixgbe_mac_operations mac_ops_x550em_a = { + .acquire_swfw_sync = ixgbe_acquire_swfw_sync_x550em_a, + .release_swfw_sync = ixgbe_release_swfw_sync_x550em_a, + .setup_fc = ixgbe_setup_fc_x550em, ++ .fc_autoneg = ixgbe_fc_autoneg, + .read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550a, + .write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550a, + }; +@@ -3017,12 +3992,11 @@ static const struct ixgbe_eeprom_operations eeprom_ops_X550EM_x = { + .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic, \ + .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic, \ + .setup_link = &ixgbe_setup_phy_link_generic, \ +- .set_phy_power = NULL, \ +- .check_overtemp = &ixgbe_tn_check_overtemp, \ +- .get_firmware_version = &ixgbe_get_phy_firmware_version_generic, ++ .set_phy_power = NULL, + + static const struct ixgbe_phy_operations phy_ops_X550 = { + X550_COMMON_PHY ++ .check_overtemp = &ixgbe_tn_check_overtemp, + .init = NULL, + .identify = &ixgbe_identify_phy_generic, + .read_reg = &ixgbe_read_phy_reg_generic, +@@ -3031,19 +4005,27 @@ static const struct ixgbe_phy_operations phy_ops_X550 = { + + static const struct ixgbe_phy_operations phy_ops_X550EM_x = { + X550_COMMON_PHY ++ .check_overtemp = &ixgbe_tn_check_overtemp, + .init = &ixgbe_init_phy_ops_X550em, + .identify = &ixgbe_identify_phy_x550em, + .read_reg = &ixgbe_read_phy_reg_generic, + .write_reg = &ixgbe_write_phy_reg_generic, +- .read_i2c_combined = &ixgbe_read_i2c_combined_generic, +- .write_i2c_combined = &ixgbe_write_i2c_combined_generic, +- .read_i2c_combined_unlocked = &ixgbe_read_i2c_combined_generic_unlocked, +- .write_i2c_combined_unlocked = +- &ixgbe_write_i2c_combined_generic_unlocked, ++}; ++ ++static const struct ixgbe_phy_operations phy_ops_x550em_x_fw = { ++ X550_COMMON_PHY ++ .check_overtemp = NULL, ++ .init = ixgbe_init_phy_ops_X550em, ++ .identify = ixgbe_identify_phy_x550em, ++ .read_reg = NULL, ++ .write_reg = NULL, ++ .read_reg_mdi = NULL, ++ .write_reg_mdi = NULL, + }; + + static const struct ixgbe_phy_operations phy_ops_x550em_a = { + X550_COMMON_PHY ++ .check_overtemp = &ixgbe_tn_check_overtemp, + .init = &ixgbe_init_phy_ops_X550em, + .identify = &ixgbe_identify_phy_x550em, + .read_reg = &ixgbe_read_phy_reg_x550a, +@@ -3052,6 +4034,31 @@ static const struct ixgbe_phy_operations phy_ops_x550em_a = { + .write_reg_mdi = &ixgbe_write_phy_reg_mdi, + }; + ++static const struct ixgbe_phy_operations phy_ops_x550em_a_fw = { ++ X550_COMMON_PHY ++ .check_overtemp = ixgbe_check_overtemp_fw, ++ .init = ixgbe_init_phy_ops_X550em, ++ .identify = ixgbe_identify_phy_fw, ++#if 0 /* Declare C22 MDI directly access functions. By hilbert */ ++ .read_reg = NULL, ++ .write_reg = NULL, ++ .read_reg_mdi = NULL, ++ .write_reg_mdi = NULL, ++#else ++ .read_reg = &ixgbe_read_phy_reg_x550a, ++ .write_reg = &ixgbe_write_phy_reg_x550a, ++ .read_reg_mdi = &ixgbe_read_phy_reg_mdio, ++ .write_reg_mdi = &ixgbe_write_phy_reg_mdio, ++#endif ++}; ++ ++static const struct ixgbe_link_operations link_ops_x550em_x = { ++ .read_link = &ixgbe_read_i2c_combined_generic, ++ .read_link_unlocked = &ixgbe_read_i2c_combined_generic_unlocked, ++ .write_link = &ixgbe_write_i2c_combined_generic, ++ .write_link_unlocked = &ixgbe_write_i2c_combined_generic_unlocked, ++}; ++ + static const u32 ixgbe_mvals_X550[IXGBE_MVALS_IDX_LIMIT] = { + IXGBE_MVALS_INIT(X550) + }; +@@ -3082,14 +4089,35 @@ const struct ixgbe_info ixgbe_X550EM_x_info = { + .phy_ops = &phy_ops_X550EM_x, + .mbx_ops = &mbx_ops_generic, + .mvals = ixgbe_mvals_X550EM_x, ++ .link_ops = &link_ops_x550em_x, ++}; ++ ++const struct ixgbe_info ixgbe_x550em_x_fw_info = { ++ .mac = ixgbe_mac_X550EM_x, ++ .get_invariants = ixgbe_get_invariants_X550_x_fw, ++ .mac_ops = &mac_ops_X550EM_x_fw, ++ .eeprom_ops = &eeprom_ops_X550EM_x, ++ .phy_ops = &phy_ops_x550em_x_fw, ++ .mbx_ops = &mbx_ops_generic, ++ .mvals = ixgbe_mvals_X550EM_x, + }; + + const struct ixgbe_info ixgbe_x550em_a_info = { + .mac = ixgbe_mac_x550em_a, +- .get_invariants = &ixgbe_get_invariants_X550_x, ++ .get_invariants = &ixgbe_get_invariants_X550_a, + .mac_ops = &mac_ops_x550em_a, + .eeprom_ops = &eeprom_ops_X550EM_x, + .phy_ops = &phy_ops_x550em_a, + .mbx_ops = &mbx_ops_generic, + .mvals = ixgbe_mvals_x550em_a, + }; ++ ++const struct ixgbe_info ixgbe_x550em_a_fw_info = { ++ .mac = ixgbe_mac_x550em_a, ++ .get_invariants = ixgbe_get_invariants_X550_a_fw, ++ .mac_ops = &mac_ops_x550em_a_fw, ++ .eeprom_ops = &eeprom_ops_X550EM_x, ++ .phy_ops = &phy_ops_x550em_a_fw, ++ .mbx_ops = &mbx_ops_generic, ++ .mvals = ixgbe_mvals_x550em_a, ++}; +-- +2.7.4 + diff --git a/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/modules/Makefile b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/modules/Makefile new file mode 100644 index 000000000000..9a4cb381bda8 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/modules/Makefile @@ -0,0 +1 @@ +obj-m:=pegatron_fn_6254_dn_f_cpld.o pegatron_hwmon_mcu.o pegatron_fn_6254_dn_f_sfp.o diff --git a/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/modules/pegatron_fn_6254_dn_f_cpld.c b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/modules/pegatron_fn_6254_dn_f_cpld.c new file mode 100644 index 000000000000..c8095b21151d --- /dev/null +++ b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/modules/pegatron_fn_6254_dn_f_cpld.c @@ -0,0 +1,1133 @@ +/* + * A CPLD driver for the fn_6254_dn_f + * + * Copyright (C) 2018 Pegatron Corporation. + * Peter5_Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef pegatron_fn_6254_dn_f_DEBUG +#ifdef pegatron_fn_6254_dn_f_DEBUG +#define DBG(x) x +#else +#define DBG(x) +#endif /* DEBUG */ + +#define CPLD_SFP_MAX_GROUP 3 +#define SFP_PORT_MAX_NUM 54 +#define SFP_EEPROM_SIZE 256 +#define QSFP_FIRST_PORT 48 +#define CPLDA_SFP_NUM 24 +#define CPLDB_SFP_NUM 12 +#define CPLDC_SFP_NUM 18 +#define CPLDA_ADDRESS 0x74 +#define CPLDB_ADDRESS 0x75 +#define CPLDC_ADDRESS 0x76 +#define CPLD_VERSION_REG 0x0 +#define SYNC_CONTROL_REG 0x1 +#define CPLD_SYS_PWR_LED_REG 0xD +#define CPLD_LOC_FAN_LED_REG 0xE +#define CPLD_EEPROM_WRITE_REG 0x12 +#define CPLD_PSU_REG 0x15 +#define SFP_13_36_SCL_BASE 0x4 +#define SFP_1_12_SCL_BASE 0x2 +#define SFP_37_54_SCL_BASE 0x5 +#define SFP_13_36_STATUS_BASE 0x8 +#define SFP_1_12_STATUS_BASE 0x5 +#define SFP_37_54_STATUS_BASE 0x9 +#define QSFP_PRESENT_ADDRESS 0xF +#define QSFP_RESET_ADDRESS_BASE 0x10 +#define QSFP_MODSELN_ADDRESS 0x17 +#define QSFP_LOW_POWER_ADDRESS 0x18 +#define CPLD_SERIAL_LED_BIT 2 +#define CPLD_EEPROM_WRITE_BIT 2 +#define SFP_PRESENT_BASE 0 +#define SFP_RXLOSS_BASE 1 +#define SFP_TXFAULT_BASE 2 +#define SFP_TXDISABLE_BASE 3 +#define CPLD_PSU_PWOK_BASE 0 +#define CPLD_PSU_PRESENT_BASE 2 +#define GET_BIT(data, bit, value) value = (data >> bit) & 0x1 +#define SET_BIT(data, bit) data |= (1 << bit) +#define CLEAR_BIT(data, bit) data &= ~(1 << bit) + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; +/* Addresses scanned for pegatron_fn_6254_dn_f_cpld + */ +static const unsigned short normal_i2c[] = { CPLDA_ADDRESS, CPLDB_ADDRESS, CPLDC_ADDRESS, I2C_CLIENT_END }; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +int pegatron_fn_6254_dn_f_cpld_read(unsigned short addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int data = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == addr) { + data = i2c_smbus_read_byte_data(cpld_node->client, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, addr, reg, data)); + break; + } + } + + mutex_unlock(&list_lock); + + return data; +} +EXPORT_SYMBOL(pegatron_fn_6254_dn_f_cpld_read); + +int pegatron_fn_6254_dn_f_cpld_write(unsigned short addr, u8 reg, u8 val) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == addr) { + ret = i2c_smbus_write_byte_data(cpld_node->client, reg, val); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, addr, reg, val)); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(pegatron_fn_6254_dn_f_cpld_write); + +static ssize_t read_cpld_HWversion(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = CPLD_VERSION_REG; + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + + return sprintf(buf, "%02x\n", (data >> 5) & 0x7); +} + +static ssize_t read_cpld_SWversion(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = CPLD_VERSION_REG; + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + + return sprintf(buf, "%02x\n", (data & 0x1f)); +} + +static ssize_t show_allled_ctrl(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = SYNC_CONTROL_REG; + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + data &= 0x3; + + return sprintf(buf, "%02x\n", data); +} + +static ssize_t set_allled_ctrl(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = SYNC_CONTROL_REG; + long val = 0; + + if (kstrtol(buf, 16, &val)) + { + return -EINVAL; + } + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + data = val | (data & 0xfc); + + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + pegatron_fn_6254_dn_f_cpld_write(client->addr, reg, data); + + return count; +} + +static ssize_t show_serial_led(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, val = 0, reg = SYNC_CONTROL_REG; + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + GET_BIT(data, CPLD_SERIAL_LED_BIT, val); + + return sprintf(buf, "%02x\n", val); +} + +static ssize_t set_serial_led(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = SYNC_CONTROL_REG; + long val = 0; + + if (kstrtol(buf, 16, &val)) + { + return -EINVAL; + } + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + if(val) + SET_BIT(data, CPLD_SERIAL_LED_BIT); + else + CLEAR_BIT(data, CPLD_SERIAL_LED_BIT); + + pegatron_fn_6254_dn_f_cpld_write(client->addr, reg, data); + + return count; +} + +static ssize_t show_sys_led(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = CPLD_SYS_PWR_LED_REG; + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + data = (data >> 5) & 0x7; + + return sprintf(buf, "%02x\n", data); +} + +static ssize_t set_sys_led(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = CPLD_SYS_PWR_LED_REG; + long val = 0; + + if (kstrtol(buf, 16, &val)) + { + return -EINVAL; + } + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + data = (val << 5) | (data & 0x1f); + + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + pegatron_fn_6254_dn_f_cpld_write(client->addr, reg, data); + + return count; +} +static ssize_t show_pwr_led(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = CPLD_SYS_PWR_LED_REG; + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + data = (data >> 2) & 0x7; + + return sprintf(buf, "%02x\n", data); +} + +static ssize_t set_pwr_led(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = CPLD_SYS_PWR_LED_REG; + long val = 0; + + + if (kstrtol(buf, 16, &val)) + { + return -EINVAL; + } + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + data = (val << 2) | (data & 0xe3); + + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + pegatron_fn_6254_dn_f_cpld_write(client->addr, reg, data); + + return count; +} +static ssize_t show_loc_led(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = CPLD_LOC_FAN_LED_REG; + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + data = (data>>4) & 0x3; + + return sprintf(buf, "%02x\n", data); +} + +static ssize_t set_loc_led(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = CPLD_LOC_FAN_LED_REG; + long val = 0; + + if (kstrtol(buf, 16, &val)) + { + return -EINVAL; + } + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + data = (val << 4) | (data & 0xf); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + pegatron_fn_6254_dn_f_cpld_write(client->addr, reg, data); + + return count; +} + +static ssize_t show_fan_led(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = CPLD_LOC_FAN_LED_REG; + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + data &= 0x7; + + return sprintf(buf, "%02x\n", data); +} + +static ssize_t set_fan_led(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = CPLD_LOC_FAN_LED_REG; + long val = 0; + + if (kstrtol(buf, 16, &val)) + { + return -EINVAL; + } + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + data = val | (data & 0xf8); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + pegatron_fn_6254_dn_f_cpld_write(client->addr, reg, data); + + return count; +} + +static ssize_t show_eeprom_write_enable(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, val = 0, reg = CPLD_EEPROM_WRITE_REG; + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + GET_BIT(data, reg, val); + + return sprintf(buf, "%02x\n", val); +} + +static ssize_t set_eeprom_write_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = CPLD_EEPROM_WRITE_REG; + long val = 0; + + if (kstrtol(buf, 16, &val)) + { + return -EINVAL; + } + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + if(val) + SET_BIT(data, CPLD_EEPROM_WRITE_BIT); + else + CLEAR_BIT(data, CPLD_EEPROM_WRITE_BIT); + + pegatron_fn_6254_dn_f_cpld_write(client->addr, reg, data); + + return count; +} + +static ssize_t read_psu_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, val = 0, reg = CPLD_PSU_REG; + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + GET_BIT(data, (CPLD_PSU_PRESENT_BASE + attr->index), val); + + return sprintf(buf, "%02x\n", val); +} + +static ssize_t read_psu_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, val=0, reg = CPLD_PSU_REG; + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + GET_BIT(data, (CPLD_PSU_PWOK_BASE + attr->index), val); + + return sprintf(buf, "%02x\n", val); +} + +#define GET_SFP_STATUS_ADDRESS(idx, reg) \ + if(idx < CPLDB_SFP_NUM) \ + reg = SFP_1_12_STATUS_BASE + (idx / 2); \ + else if(idx < CPLDA_SFP_NUM + CPLDB_SFP_NUM) \ + reg = SFP_13_36_STATUS_BASE + ((idx-CPLDB_SFP_NUM) / 2); \ + else \ + reg = SFP_37_54_STATUS_BASE + ((idx-CPLDB_SFP_NUM-CPLDA_SFP_NUM) / 2) + +static ssize_t get_sfp_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + u8 reg = 0, data = 0, val = 0; + + GET_SFP_STATUS_ADDRESS(attr->index, reg); + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + GET_BIT(data, SFP_PRESENT_BASE + 4*(attr->index % 2), val); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t get_sfp_tx_disable(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + u8 reg = 0, data = 0, val = 0; + + GET_SFP_STATUS_ADDRESS(attr->index, reg); + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + GET_BIT(data, SFP_TXDISABLE_BASE + 4*(attr->index % 2), val); + + return sprintf(buf, "%d\n", val); +} +static ssize_t set_sfp_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + u8 reg = 0, data = 0; + long val = 0; + + if (kstrtol(buf, 16, &val)) + { + return -EINVAL; + } + + GET_SFP_STATUS_ADDRESS(attr->index, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + + if(val) + SET_BIT(data, SFP_TXDISABLE_BASE + 4*(attr->index % 2)); + else + CLEAR_BIT(data, SFP_TXDISABLE_BASE + 4*(attr->index % 2)); + + pegatron_fn_6254_dn_f_cpld_write(client->addr, reg, data); + + return count; +} +static ssize_t get_sfp_rx_loss(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + u8 reg = 0, data = 0, val = 0; + + GET_SFP_STATUS_ADDRESS(attr->index, reg); + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + GET_BIT(data, SFP_RXLOSS_BASE + 4*(attr->index % 2), val); + + return sprintf(buf, "%d\n", val); +} +static ssize_t get_sfp_tx_fault(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + u8 reg = 0, data = 0, val = 0; + + GET_SFP_STATUS_ADDRESS(attr->index, reg); + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + GET_BIT(data, SFP_TXFAULT_BASE + 4*(attr->index % 2), val); + + return sprintf(buf, "%d\n",val); +} + +static ssize_t get_qsfp_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, val = 0, reg = QSFP_PRESENT_ADDRESS; + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + GET_BIT(data, (attr->index % QSFP_FIRST_PORT), val); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t get_qsfp_reset(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + u8 reg = (QSFP_RESET_ADDRESS_BASE + attr->index % QSFP_FIRST_PORT / 4), data =0; + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + data = (data >> ((attr->index % QSFP_FIRST_PORT % 4)*2)) & 0x3; + + return sprintf(buf, "%d\n", data); +} + +static ssize_t set_qsfp_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + u8 reg = (QSFP_RESET_ADDRESS_BASE + attr->index % QSFP_FIRST_PORT / 4), data = 0; + long val = 0; + + if (kstrtol(buf, 16, &val)) + { + return -EINVAL; + } + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + CLEAR_BIT(data, (attr->index % 4)*2); + CLEAR_BIT(data, (attr->index % 4)*2+1); + data |= (val & 0x3) << ((attr->index % QSFP_FIRST_PORT % 4)*2); + + pegatron_fn_6254_dn_f_cpld_write(client->addr, reg, data); + + return count; +} + +static ssize_t get_qsfp_lowpower(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, val = 0, reg = QSFP_LOW_POWER_ADDRESS; + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + GET_BIT(data, (attr->index % QSFP_FIRST_PORT), val); + return sprintf(buf, "%02x\n", val); +} + +static ssize_t set_qsfp_lowpower(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = QSFP_LOW_POWER_ADDRESS; + long val = 0; + + if (kstrtol(buf, 16, &val)) + { + return -EINVAL; + } + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + if(val) + SET_BIT(data, (attr->index % QSFP_FIRST_PORT)); + else + CLEAR_BIT(data, (attr->index % QSFP_FIRST_PORT)); + + pegatron_fn_6254_dn_f_cpld_write(client->addr, reg, data); + + return count; +} + +static ssize_t get_qsfp_modeseln(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, val = 0, reg = QSFP_MODSELN_ADDRESS; + + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + GET_BIT(data, (attr->index % QSFP_FIRST_PORT), val); + return sprintf(buf, "%02x\n", val); +} + +static ssize_t set_qsfp_modeseln(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + u8 data = 0, reg = QSFP_MODSELN_ADDRESS; + long val = 0; + + if (kstrtol(buf, 16, &val)) + { + return -EINVAL; + } + data = pegatron_fn_6254_dn_f_cpld_read(client->addr, reg); + DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data)); + if(val) + SET_BIT(data, (attr->index % QSFP_FIRST_PORT)); + else + CLEAR_BIT(data, (attr->index % QSFP_FIRST_PORT)); + + pegatron_fn_6254_dn_f_cpld_write(client->addr, reg, data); + + return count; +} + +static SENSOR_DEVICE_ATTR(cpld_hw_version, S_IRUGO, read_cpld_HWversion, NULL, 0); +static SENSOR_DEVICE_ATTR(cpld_sw_version, S_IRUGO, read_cpld_SWversion, NULL, 0); +static SENSOR_DEVICE_ATTR(cpld_allled_ctrl, S_IRUGO | S_IWUSR, show_allled_ctrl, set_allled_ctrl, 0); +static SENSOR_DEVICE_ATTR(serial_led_enable, S_IRUGO | S_IWUSR, show_serial_led, set_serial_led, 0); +static SENSOR_DEVICE_ATTR(sys_led, S_IRUGO | S_IWUSR, show_sys_led, set_sys_led, 0); +static SENSOR_DEVICE_ATTR(pwr_led, S_IRUGO | S_IWUSR, show_pwr_led, set_pwr_led, 0); +static SENSOR_DEVICE_ATTR(loc_led, S_IRUGO | S_IWUSR, show_loc_led, set_loc_led, 0); +static SENSOR_DEVICE_ATTR(fan_led, S_IRUGO | S_IWUSR, show_fan_led, set_fan_led, 0); +static SENSOR_DEVICE_ATTR(eeprom_write_enable, S_IRUGO | S_IWUSR, show_eeprom_write_enable, set_eeprom_write_enable, 0); +static SENSOR_DEVICE_ATTR(psu_1_present, S_IRUGO, read_psu_present, NULL, 1); +static SENSOR_DEVICE_ATTR(psu_2_present, S_IRUGO, read_psu_present, NULL, 0); +static SENSOR_DEVICE_ATTR(psu_1_status, S_IRUGO, read_psu_status, NULL, 1); +static SENSOR_DEVICE_ATTR(psu_2_status, S_IRUGO, read_psu_status, NULL, 0); + +#define SET_SFP_ATTR(_num) \ + static SENSOR_DEVICE_ATTR(sfp##_num##_present, S_IRUGO, get_sfp_present, NULL, _num-1); \ + static SENSOR_DEVICE_ATTR(sfp##_num##_tx_disable, S_IRUGO | S_IWUSR, get_sfp_tx_disable, set_sfp_tx_disable, _num-1); \ + static SENSOR_DEVICE_ATTR(sfp##_num##_rx_loss, S_IRUGO, get_sfp_rx_loss, NULL, _num-1); \ + static SENSOR_DEVICE_ATTR(sfp##_num##_tx_fault, S_IRUGO, get_sfp_tx_fault, NULL, _num-1) + +#define SET_QSFP_ATTR(_num) \ + static SENSOR_DEVICE_ATTR(sfp##_num##_present, S_IRUGO, get_qsfp_present, NULL, _num-1); \ + static SENSOR_DEVICE_ATTR(sfp##_num##_reset, S_IRUGO | S_IWUSR, get_qsfp_reset, set_qsfp_reset, _num-1); \ + static SENSOR_DEVICE_ATTR(sfp##_num##_lowpower, S_IRUGO | S_IWUSR, get_qsfp_lowpower, set_qsfp_lowpower, _num-1); \ + static SENSOR_DEVICE_ATTR(sfp##_num##_modeseln, S_IRUGO | S_IWUSR, get_qsfp_modeseln, set_qsfp_modeseln, _num-1) + +SET_SFP_ATTR(1);SET_SFP_ATTR(2);SET_SFP_ATTR(3);SET_SFP_ATTR(4);SET_SFP_ATTR(5);SET_SFP_ATTR(6);SET_SFP_ATTR(7);SET_SFP_ATTR(8);SET_SFP_ATTR(9); +SET_SFP_ATTR(10);SET_SFP_ATTR(11);SET_SFP_ATTR(12);SET_SFP_ATTR(13);SET_SFP_ATTR(14);SET_SFP_ATTR(15);SET_SFP_ATTR(16);SET_SFP_ATTR(17);SET_SFP_ATTR(18); +SET_SFP_ATTR(19);SET_SFP_ATTR(20);SET_SFP_ATTR(21);SET_SFP_ATTR(22);SET_SFP_ATTR(23);SET_SFP_ATTR(24);SET_SFP_ATTR(25);SET_SFP_ATTR(26);SET_SFP_ATTR(27); +SET_SFP_ATTR(28);SET_SFP_ATTR(29);SET_SFP_ATTR(30);SET_SFP_ATTR(31);SET_SFP_ATTR(32);SET_SFP_ATTR(33);SET_SFP_ATTR(34);SET_SFP_ATTR(35);SET_SFP_ATTR(36); +SET_SFP_ATTR(37);SET_SFP_ATTR(38);SET_SFP_ATTR(39);SET_SFP_ATTR(40);SET_SFP_ATTR(41);SET_SFP_ATTR(42);SET_SFP_ATTR(43);SET_SFP_ATTR(44);SET_SFP_ATTR(45); +SET_SFP_ATTR(46);SET_SFP_ATTR(47);SET_SFP_ATTR(48); +SET_QSFP_ATTR(49);SET_QSFP_ATTR(50);SET_QSFP_ATTR(51);SET_QSFP_ATTR(52);SET_QSFP_ATTR(53);SET_QSFP_ATTR(54); + +static struct attribute *pegatron_fn_6254_dn_f_cpldA_attributes[] = { + &sensor_dev_attr_cpld_hw_version.dev_attr.attr, + &sensor_dev_attr_cpld_sw_version.dev_attr.attr, + + &sensor_dev_attr_sfp13_present.dev_attr.attr, + &sensor_dev_attr_sfp13_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp13_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp13_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp14_present.dev_attr.attr, + &sensor_dev_attr_sfp14_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp14_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp14_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp15_present.dev_attr.attr, + &sensor_dev_attr_sfp15_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp15_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp15_tx_fault.dev_attr.attr, + + + &sensor_dev_attr_sfp16_present.dev_attr.attr, + &sensor_dev_attr_sfp16_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp16_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp16_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp17_present.dev_attr.attr, + &sensor_dev_attr_sfp17_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp17_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp17_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp18_present.dev_attr.attr, + &sensor_dev_attr_sfp18_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp18_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp18_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp19_present.dev_attr.attr, + &sensor_dev_attr_sfp19_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp19_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp19_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp20_present.dev_attr.attr, + &sensor_dev_attr_sfp20_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp20_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp20_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp21_present.dev_attr.attr, + &sensor_dev_attr_sfp21_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp21_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp21_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp22_present.dev_attr.attr, + &sensor_dev_attr_sfp22_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp22_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp22_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp23_present.dev_attr.attr, + &sensor_dev_attr_sfp23_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp23_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp23_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp24_present.dev_attr.attr, + &sensor_dev_attr_sfp24_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp24_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp24_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp25_present.dev_attr.attr, + &sensor_dev_attr_sfp25_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp25_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp25_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp26_present.dev_attr.attr, + &sensor_dev_attr_sfp26_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp26_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp26_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp27_present.dev_attr.attr, + &sensor_dev_attr_sfp27_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp27_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp27_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp28_present.dev_attr.attr, + &sensor_dev_attr_sfp28_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp28_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp28_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp29_present.dev_attr.attr, + &sensor_dev_attr_sfp29_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp29_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp29_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp30_present.dev_attr.attr, + &sensor_dev_attr_sfp30_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp30_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp30_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp31_present.dev_attr.attr, + &sensor_dev_attr_sfp31_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp31_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp31_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp32_present.dev_attr.attr, + &sensor_dev_attr_sfp32_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp32_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp32_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp33_present.dev_attr.attr, + &sensor_dev_attr_sfp33_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp33_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp33_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp34_present.dev_attr.attr, + &sensor_dev_attr_sfp34_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp34_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp34_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp35_present.dev_attr.attr, + &sensor_dev_attr_sfp35_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp35_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp35_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp36_present.dev_attr.attr, + &sensor_dev_attr_sfp36_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp36_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp36_tx_fault.dev_attr.attr, + + NULL +}; + +static struct attribute *pegatron_fn_6254_dn_f_cpldB_attributes[] = { + &sensor_dev_attr_cpld_hw_version.dev_attr.attr, + &sensor_dev_attr_cpld_sw_version.dev_attr.attr, + &sensor_dev_attr_cpld_allled_ctrl.dev_attr.attr, + &sensor_dev_attr_serial_led_enable.dev_attr.attr, + &sensor_dev_attr_sys_led.dev_attr.attr, + &sensor_dev_attr_pwr_led.dev_attr.attr, + &sensor_dev_attr_loc_led.dev_attr.attr, + &sensor_dev_attr_fan_led.dev_attr.attr, + &sensor_dev_attr_eeprom_write_enable.dev_attr.attr, + &sensor_dev_attr_psu_1_present.dev_attr.attr, + &sensor_dev_attr_psu_2_present.dev_attr.attr, + &sensor_dev_attr_psu_1_status.dev_attr.attr, + &sensor_dev_attr_psu_2_status.dev_attr.attr, + + &sensor_dev_attr_sfp1_present.dev_attr.attr, + &sensor_dev_attr_sfp1_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp1_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp1_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp2_present.dev_attr.attr, + &sensor_dev_attr_sfp2_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp2_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp2_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp3_present.dev_attr.attr, + &sensor_dev_attr_sfp3_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp3_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp3_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp4_present.dev_attr.attr, + &sensor_dev_attr_sfp4_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp4_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp4_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp5_present.dev_attr.attr, + &sensor_dev_attr_sfp5_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp5_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp5_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp6_present.dev_attr.attr, + &sensor_dev_attr_sfp6_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp6_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp6_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp7_present.dev_attr.attr, + &sensor_dev_attr_sfp7_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp7_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp7_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp8_present.dev_attr.attr, + &sensor_dev_attr_sfp8_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp8_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp8_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp9_present.dev_attr.attr, + &sensor_dev_attr_sfp9_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp9_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp9_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp10_present.dev_attr.attr, + &sensor_dev_attr_sfp10_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp10_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp10_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp11_present.dev_attr.attr, + &sensor_dev_attr_sfp11_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp11_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp11_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp12_present.dev_attr.attr, + &sensor_dev_attr_sfp12_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp12_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp12_tx_fault.dev_attr.attr, + NULL +}; + +static struct attribute *pegatron_fn_6254_dn_f_cpldC_attributes[] = { + &sensor_dev_attr_cpld_hw_version.dev_attr.attr, + &sensor_dev_attr_cpld_sw_version.dev_attr.attr, + + &sensor_dev_attr_sfp37_present.dev_attr.attr, + &sensor_dev_attr_sfp37_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp37_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp37_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp38_present.dev_attr.attr, + &sensor_dev_attr_sfp38_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp38_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp38_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp39_present.dev_attr.attr, + &sensor_dev_attr_sfp39_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp39_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp39_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp40_present.dev_attr.attr, + &sensor_dev_attr_sfp40_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp40_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp40_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp41_present.dev_attr.attr, + &sensor_dev_attr_sfp41_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp41_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp41_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp42_present.dev_attr.attr, + &sensor_dev_attr_sfp42_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp42_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp42_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp43_present.dev_attr.attr, + &sensor_dev_attr_sfp43_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp43_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp43_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp44_present.dev_attr.attr, + &sensor_dev_attr_sfp44_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp44_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp44_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp45_present.dev_attr.attr, + &sensor_dev_attr_sfp45_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp45_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp45_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp46_present.dev_attr.attr, + &sensor_dev_attr_sfp46_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp46_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp46_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp47_present.dev_attr.attr, + &sensor_dev_attr_sfp47_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp47_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp47_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp48_present.dev_attr.attr, + &sensor_dev_attr_sfp48_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp48_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp48_tx_fault.dev_attr.attr, + + &sensor_dev_attr_sfp49_present.dev_attr.attr, + &sensor_dev_attr_sfp49_lowpower.dev_attr.attr, + &sensor_dev_attr_sfp49_modeseln.dev_attr.attr, + &sensor_dev_attr_sfp49_reset.dev_attr.attr, + + &sensor_dev_attr_sfp50_present.dev_attr.attr, + &sensor_dev_attr_sfp50_lowpower.dev_attr.attr, + &sensor_dev_attr_sfp50_modeseln.dev_attr.attr, + &sensor_dev_attr_sfp50_reset.dev_attr.attr, + + &sensor_dev_attr_sfp51_present.dev_attr.attr, + &sensor_dev_attr_sfp51_lowpower.dev_attr.attr, + &sensor_dev_attr_sfp51_modeseln.dev_attr.attr, + &sensor_dev_attr_sfp51_reset.dev_attr.attr, + + &sensor_dev_attr_sfp52_present.dev_attr.attr, + &sensor_dev_attr_sfp52_lowpower.dev_attr.attr, + &sensor_dev_attr_sfp52_modeseln.dev_attr.attr, + &sensor_dev_attr_sfp52_reset.dev_attr.attr, + + &sensor_dev_attr_sfp53_present.dev_attr.attr, + &sensor_dev_attr_sfp53_lowpower.dev_attr.attr, + &sensor_dev_attr_sfp53_modeseln.dev_attr.attr, + &sensor_dev_attr_sfp53_reset.dev_attr.attr, + + &sensor_dev_attr_sfp54_present.dev_attr.attr, + &sensor_dev_attr_sfp54_lowpower.dev_attr.attr, + &sensor_dev_attr_sfp54_modeseln.dev_attr.attr, + &sensor_dev_attr_sfp54_reset.dev_attr.attr, + NULL +}; + +static const struct attribute_group pegatron_fn_6254_dn_f_cpldA_group = { .attrs = pegatron_fn_6254_dn_f_cpldA_attributes}; +static const struct attribute_group pegatron_fn_6254_dn_f_cpldB_group = { .attrs = pegatron_fn_6254_dn_f_cpldB_attributes}; +static const struct attribute_group pegatron_fn_6254_dn_f_cpldC_group = { .attrs = pegatron_fn_6254_dn_f_cpldC_attributes}; + +static void pegatron_fn_6254_dn_f_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void pegatron_fn_6254_dn_f_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static int pegatron_fn_6254_dn_f_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + /* Register sysfs hooks */ + switch(client->addr) + { + case CPLDA_ADDRESS: + status = sysfs_create_group(&client->dev.kobj, &pegatron_fn_6254_dn_f_cpldA_group); + break; + case CPLDB_ADDRESS: + status = sysfs_create_group(&client->dev.kobj, &pegatron_fn_6254_dn_f_cpldB_group); + break; + case CPLDC_ADDRESS: + status = sysfs_create_group(&client->dev.kobj, &pegatron_fn_6254_dn_f_cpldC_group); + break; + default: + dev_dbg(&client->dev, "i2c_check_CPLD failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + break; + } + + if (status) { + goto exit; + } + + dev_info(&client->dev, "chip found\n"); + pegatron_fn_6254_dn_f_cpld_add_client(client); + + return 0; + +exit: + return status; +} + +static int pegatron_fn_6254_dn_f_cpld_remove(struct i2c_client *client) +{ + switch(client->addr) + { + case CPLDA_ADDRESS: + sysfs_remove_group(&client->dev.kobj, &pegatron_fn_6254_dn_f_cpldA_group); + break; + case CPLDB_ADDRESS: + sysfs_remove_group(&client->dev.kobj, &pegatron_fn_6254_dn_f_cpldB_group); + break; + case CPLDC_ADDRESS: + sysfs_remove_group(&client->dev.kobj, &pegatron_fn_6254_dn_f_cpldC_group); + break; + default: + dev_dbg(&client->dev, "i2c_remove_CPLD failed (0x%x)\n", client->addr); + break; + } + + + pegatron_fn_6254_dn_f_cpld_remove_client(client); + return 0; +} + +static const struct i2c_device_id pegatron_fn_6254_dn_f_cpld_id[] = { + { "fn_6254_dn_f_cpld", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, pegatron_fn_6254_dn_f_cpld_id); + +static struct i2c_driver pegatron_fn_6254_dn_f_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "pegatron_fn_6254_dn_f_cpld", + }, + .probe = pegatron_fn_6254_dn_f_cpld_probe, + .remove = pegatron_fn_6254_dn_f_cpld_remove, + .id_table = pegatron_fn_6254_dn_f_cpld_id, + .address_list = normal_i2c, +}; + +static int __init pegatron_fn_6254_dn_f_cpld_init(void) +{ + mutex_init(&list_lock); + + return i2c_add_driver(&pegatron_fn_6254_dn_f_cpld_driver); +} + +static void __exit pegatron_fn_6254_dn_f_cpld_exit(void) +{ + i2c_del_driver(&pegatron_fn_6254_dn_f_cpld_driver); +} + +MODULE_AUTHOR("Peter5 Lin "); +MODULE_DESCRIPTION("pegatron_fn_6254_dn_f_cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(pegatron_fn_6254_dn_f_cpld_init); +module_exit(pegatron_fn_6254_dn_f_cpld_exit); diff --git a/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/modules/pegatron_fn_6254_dn_f_sfp.c b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/modules/pegatron_fn_6254_dn_f_sfp.c new file mode 100644 index 000000000000..c9a5d576ce71 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/modules/pegatron_fn_6254_dn_f_sfp.c @@ -0,0 +1,431 @@ +/* + * A SFP driver for the fn_6254_dn_f platform + * + * Copyright (C) 2018 Pegatron Corporation. + * Peter5_Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef PEGA_DEBUG +/*#define PEGA_DEBUG*/ +#ifdef PEGA_DEBUG +#define DBG(x) x +#else +#define DBG(x) +#endif /* DEBUG */ + +#define SFP_EEPROM_SIZE 256 +#define SFP_EEPROM_A0_ADDR 0x50 +#define SFP_EEPROM_A2_ADDR 0x51 +#define SFP_EEPROM_BUS_TYPE I2C_SMBUS_I2C_BLOCK_DATA +#define CPLDA_SFP_NUM 24 +#define CPLDB_SFP_NUM 12 +#define CPLDC_SFP_NUM 18 +#define CPLDA_ADDRESS 0x74 +#define CPLDB_ADDRESS 0x75 +#define CPLDC_ADDRESS 0x76 +#define SFP_13_36_SCL_BASE 0x4 +#define SFP_1_12_SCL_BASE 0x2 +#define SFP_37_54_SCL_BASE 0x5 +#define QSFP_I2C_ENABLE_BASE 0x17 +#define GET_BIT(data, bit, value) value = (data >> bit) & 0x1 +#define SET_BIT(data, bit) data |= (1 << bit) +#define CLEAR_BIT(data, bit) data &= ~(1 << bit) + +enum cpld_croups { cpld_group_a, cpld_group_b, cpld_group_c}; + +static const unsigned short normal_i2c[] = { SFP_EEPROM_A0_ADDR, SFP_EEPROM_A2_ADDR, I2C_CLIENT_END }; +static char SFP_CPLD_GROUPA_MAPPING[CPLDA_SFP_NUM][16]={0}; +static char SFP_CPLD_GROUPB_MAPPING[CPLDB_SFP_NUM][16]={0}; +static char SFP_CPLD_GROUPC_MAPPING[CPLDC_SFP_NUM][16]={0}; + +/* + * This parameter is to help this driver avoid blocking other drivers out + * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C + * clock, one 256 byte read takes about 1/43 second which is excessive; + * but the 1/170 second it takes at 400 kHz may be quite reasonable; and + * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible. + * + * This value is forced to be a power of two so that writes align on pages. + */ +static unsigned io_limit = 128; +module_param(io_limit, uint, 0); +MODULE_PARM_DESC(io_limit, "Maximum bytes per I/O (default 128)"); + +/* + * Specs often allow 5 msec for a page write, sometimes 20 msec; + * it's important to recover from write timeouts. + */ +static unsigned write_timeout = 25; +module_param(write_timeout, uint, 0); +MODULE_PARM_DESC(write_timeout, "Time (in ms) to try writes (default 25)"); + + +struct fn_6254_dn_f_sfp_data { + struct mutex lock; + struct bin_attribute bin; + int use_smbus; + kernel_ulong_t driver_data; + + struct i2c_client *client; +}; + +extern int pegatron_fn_6254_dn_f_cpld_read(unsigned short cpld_addr, u8 reg); +extern int pegatron_fn_6254_dn_f_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +static ssize_t fn_6254_dn_f_sfp_eeprom_read(struct fn_6254_dn_f_sfp_data *data, char *buf, + unsigned offset, size_t count) +{ + struct i2c_msg msg[2]; + u8 msgbuf[2]; + struct i2c_client *client = data->client; + unsigned long timeout, read_time; + int status; + + memset(msg, 0, sizeof(msg)); + + if (count > io_limit) + count = io_limit; + + /* Smaller eeproms can work given some SMBus extension calls */ + if (count > I2C_SMBUS_BLOCK_MAX) + count = I2C_SMBUS_BLOCK_MAX; + + /* + * Reads fail if the previous write didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + read_time = jiffies; + switch (data->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + status = i2c_smbus_read_i2c_block_data(client, offset, + count, buf); + break; + case I2C_SMBUS_WORD_DATA: + status = i2c_smbus_read_word_data(client, offset); + if (status >= 0) { + buf[0] = status & 0xff; + if (count == 2) + buf[1] = status >> 8; + status = count; + } + break; + case I2C_SMBUS_BYTE_DATA: + status = i2c_smbus_read_byte_data(client, offset); + if (status >= 0) { + buf[0] = status; + status = count; + } + break; + default: + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + status = count; + } + dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(read_time, timeout)); + + return -ETIMEDOUT; +} + +static ssize_t fn_6254_dn_f_sfp_read(struct fn_6254_dn_f_sfp_data *data, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) + return count; + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->lock); + + while (count) { + ssize_t status; + + status = fn_6254_dn_f_sfp_eeprom_read(data, buf, off, count); + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->lock); + + return retval; +} + +static ssize_t +fn_6254_dn_f_sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int i; + u8 cpldData = 0; + struct fn_6254_dn_f_sfp_data *data; + + /*SFP 1-12*/ + for(i=0; iattr.name, SFP_CPLD_GROUPB_MAPPING[i])) + { + pegatron_fn_6254_dn_f_cpld_write(CPLDB_ADDRESS, SFP_1_12_SCL_BASE, i+1); + goto check_done; + } + } + /*SFP 13-36*/ + for(i=0; iattr.name, SFP_CPLD_GROUPA_MAPPING[i])) + { + pegatron_fn_6254_dn_f_cpld_write(CPLDA_ADDRESS, SFP_13_36_SCL_BASE, i+1); + goto check_done; + } + } + + /*SFP 37-54*/ + for(i=0; iattr.name, SFP_CPLD_GROUPC_MAPPING[i])) + { + /* Enable QSFP i2c function */ + if(i >= 12) + { + cpldData = 0xff; + cpldData = pegatron_fn_6254_dn_f_cpld_read(CPLDC_ADDRESS, QSFP_I2C_ENABLE_BASE); + CLEAR_BIT(cpldData, i-12); + pegatron_fn_6254_dn_f_cpld_write(CPLDC_ADDRESS, QSFP_I2C_ENABLE_BASE, cpldData); + } + pegatron_fn_6254_dn_f_cpld_write(CPLDC_ADDRESS, SFP_37_54_SCL_BASE, i+1); + goto check_done; + } + } + +check_done: + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + return fn_6254_dn_f_sfp_read(data, buf, off, count); +} + +#define SFP_EEPROM_ATTR(_num) \ + static struct bin_attribute sfp##_num##_eeprom_attr = { \ + .attr = { \ + .name = __stringify(sfp##_num##_eeprom), \ + .mode = S_IRUGO\ + }, \ + .size = SFP_EEPROM_SIZE, \ + .read = fn_6254_dn_f_sfp_bin_read, \ + } + +SFP_EEPROM_ATTR(1);SFP_EEPROM_ATTR(2);SFP_EEPROM_ATTR(3);SFP_EEPROM_ATTR(4);SFP_EEPROM_ATTR(5);SFP_EEPROM_ATTR(6);SFP_EEPROM_ATTR(7);SFP_EEPROM_ATTR(8);SFP_EEPROM_ATTR(9); +SFP_EEPROM_ATTR(10);SFP_EEPROM_ATTR(11);SFP_EEPROM_ATTR(12);SFP_EEPROM_ATTR(13);SFP_EEPROM_ATTR(14);SFP_EEPROM_ATTR(15);SFP_EEPROM_ATTR(16);SFP_EEPROM_ATTR(17);SFP_EEPROM_ATTR(18); +SFP_EEPROM_ATTR(19);SFP_EEPROM_ATTR(20);SFP_EEPROM_ATTR(21);SFP_EEPROM_ATTR(22);SFP_EEPROM_ATTR(23);SFP_EEPROM_ATTR(24);SFP_EEPROM_ATTR(25);SFP_EEPROM_ATTR(26);SFP_EEPROM_ATTR(27); +SFP_EEPROM_ATTR(28);SFP_EEPROM_ATTR(29);SFP_EEPROM_ATTR(30);SFP_EEPROM_ATTR(31);SFP_EEPROM_ATTR(32);SFP_EEPROM_ATTR(33);SFP_EEPROM_ATTR(34);SFP_EEPROM_ATTR(35);SFP_EEPROM_ATTR(36); +SFP_EEPROM_ATTR(37);SFP_EEPROM_ATTR(38);SFP_EEPROM_ATTR(39);SFP_EEPROM_ATTR(40);SFP_EEPROM_ATTR(41);SFP_EEPROM_ATTR(42);SFP_EEPROM_ATTR(43);SFP_EEPROM_ATTR(44);SFP_EEPROM_ATTR(45); +SFP_EEPROM_ATTR(46);SFP_EEPROM_ATTR(47);SFP_EEPROM_ATTR(48);SFP_EEPROM_ATTR(49);SFP_EEPROM_ATTR(50);SFP_EEPROM_ATTR(51);SFP_EEPROM_ATTR(52);SFP_EEPROM_ATTR(53);SFP_EEPROM_ATTR(54); + +static struct bin_attribute *fn_6254_dn_f_cpldA_sfp_epprom_attributes[] = { + &sfp13_eeprom_attr, &sfp14_eeprom_attr, &sfp15_eeprom_attr, &sfp16_eeprom_attr, &sfp17_eeprom_attr, &sfp18_eeprom_attr, &sfp19_eeprom_attr, &sfp20_eeprom_attr, + &sfp21_eeprom_attr, &sfp22_eeprom_attr, &sfp23_eeprom_attr, &sfp24_eeprom_attr, &sfp25_eeprom_attr, &sfp26_eeprom_attr, &sfp27_eeprom_attr, &sfp28_eeprom_attr, + &sfp29_eeprom_attr, &sfp30_eeprom_attr, &sfp31_eeprom_attr, &sfp32_eeprom_attr, &sfp33_eeprom_attr, &sfp34_eeprom_attr, &sfp35_eeprom_attr, &sfp36_eeprom_attr, + NULL +}; + +static struct bin_attribute *fn_6254_dn_f_cpldB_sfp_epprom_attributes[] = { + &sfp1_eeprom_attr, &sfp2_eeprom_attr, &sfp3_eeprom_attr, &sfp4_eeprom_attr, &sfp5_eeprom_attr, &sfp6_eeprom_attr, &sfp7_eeprom_attr, &sfp8_eeprom_attr, + &sfp9_eeprom_attr, &sfp10_eeprom_attr, &sfp11_eeprom_attr, &sfp12_eeprom_attr, + NULL +}; + +static struct bin_attribute *fn_6254_dn_f_cpldC_sfp_epprom_attributes[] = { + &sfp37_eeprom_attr, &sfp38_eeprom_attr, &sfp39_eeprom_attr, &sfp40_eeprom_attr, &sfp41_eeprom_attr, &sfp42_eeprom_attr, &sfp43_eeprom_attr, &sfp44_eeprom_attr, + &sfp45_eeprom_attr, &sfp46_eeprom_attr, &sfp47_eeprom_attr, &sfp48_eeprom_attr, &sfp49_eeprom_attr, &sfp50_eeprom_attr, &sfp51_eeprom_attr, &sfp52_eeprom_attr, + &sfp53_eeprom_attr, &sfp54_eeprom_attr, + NULL +}; + +static const struct attribute_group fn_6254_dn_f_sfpA_group = { .bin_attrs = fn_6254_dn_f_cpldA_sfp_epprom_attributes}; +static const struct attribute_group fn_6254_dn_f_sfpB_group = { .bin_attrs = fn_6254_dn_f_cpldB_sfp_epprom_attributes}; +static const struct attribute_group fn_6254_dn_f_sfpC_group = { .bin_attrs = fn_6254_dn_f_cpldC_sfp_epprom_attributes}; + +static int fn_6254_dn_f_sfp_device_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + int use_smbus = SFP_EEPROM_BUS_TYPE; + struct fn_6254_dn_f_sfp_data *data; + int err, i; + unsigned num_addresses; + kernel_ulong_t magic; + + data = kzalloc(sizeof(struct fn_6254_dn_f_sfp_data) , GFP_KERNEL); + if (!data) + return -ENOMEM; + + mutex_init(&data->lock); + data->use_smbus = use_smbus; + /* + * Export the EEPROM bytes through sysfs, since that's convenient. + * By default, only root should see the data (maybe passwords etc) + */ + + data->client = client; + data->driver_data = dev_id->driver_data; + + sysfs_bin_attr_init(&data->bin); + + switch(dev_id->driver_data) + { + case cpld_group_a: + err = sysfs_create_group(&client->dev.kobj, &fn_6254_dn_f_sfpA_group); + if (err) + goto err_clients; + break; + case cpld_group_b: + err = sysfs_create_group(&client->dev.kobj, &fn_6254_dn_f_sfpB_group); + if (err) + goto err_clients; + break; + case cpld_group_c: + err = sysfs_create_group(&client->dev.kobj, &fn_6254_dn_f_sfpC_group); + if (err) + goto err_clients; + break; + default: + printk(KERN_ALERT "i2c_check_CPLD failed\n"); + err = -EIO; + break; + } + + i2c_set_clientdata(client, data); + + return 0; + +err_clients: + kfree(data); + return err; +} + +static int fn_6254_dn_f_sfp_device_remove(struct i2c_client *client) +{ + struct fn_6254_dn_f_sfp_data *data; + int i; + + data = i2c_get_clientdata(client); + + switch(data->driver_data) + { + case cpld_group_a: + sysfs_remove_group(&client->dev.kobj, &fn_6254_dn_f_sfpA_group); + break; + case cpld_group_b: + sysfs_remove_group(&client->dev.kobj, &fn_6254_dn_f_sfpB_group); + break; + case cpld_group_c: + sysfs_remove_group(&client->dev.kobj, &fn_6254_dn_f_sfpC_group); + break; + default: + dev_dbg(&client->dev, "i2c_remove_CPLD failed (0x%x)\n", client->addr); + break; + } + + + return 0; +} + +static const struct i2c_device_id fn_6254_dn_f_sfp_id[] = { + { "fn_6254_dn_f_sfpA", cpld_group_a }, + { "fn_6254_dn_f_sfpB", cpld_group_b }, + { "fn_6254_dn_f_sfpC", cpld_group_c }, + {} +}; +MODULE_DEVICE_TABLE(i2c, fn_6254_dn_f_sfp_id); + +static struct i2c_driver fn_6254_dn_f_sfp_driver = { + .driver = { + .name = "pegatron_fn_6254_dn_f_sfp", + }, + .probe = fn_6254_dn_f_sfp_device_probe, + .remove = fn_6254_dn_f_sfp_device_remove, + .id_table = fn_6254_dn_f_sfp_id, + .address_list = normal_i2c, +}; + +static int __init fn_6254_dn_f_sfp_init(void) +{ + int i; + + /*SFP 1-12*/ + for(i=0; i"); +MODULE_DESCRIPTION("fn_6254_dn_f_cpld_mux driver"); +MODULE_LICENSE("GPL"); + +module_init(fn_6254_dn_f_sfp_init); +module_exit(fn_6254_dn_f_sfp_exit); + diff --git a/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/modules/pegatron_hwmon_mcu.c b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/modules/pegatron_hwmon_mcu.c new file mode 120000 index 000000000000..1357104478a3 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/modules/pegatron_hwmon_mcu.c @@ -0,0 +1 @@ +../../common/modules/pegatron_hwmon_mcu.c \ No newline at end of file diff --git a/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/scripts/sensors b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/scripts/sensors new file mode 100755 index 000000000000..6bc6097bc17a --- /dev/null +++ b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/scripts/sensors @@ -0,0 +1,7 @@ +#!/bin/bash +docker exec -i pmon sensors "$@" + +#To probe sensors not part of lm-sensors +if [ -r /usr/local/bin/fn_6254_dn_f_sensors.py ]; then + python /usr/local/bin/fn_6254_dn_f_sensors.py get_sensors +fi diff --git a/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/service/fn_6254_dn_f-platform-init.service b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/service/fn_6254_dn_f-platform-init.service new file mode 100644 index 000000000000..2cdd391d1556 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/service/fn_6254_dn_f-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Pegastron fn-6254-dn-f Platform initialization service +After=local-fs.target +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/pegatron_fn_6254_dn_f_util.py install +ExecStop=/usr/local/bin/pegatron_fn_6254_dn_f_util.py uninstall +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/utils/fn_6254_dn_f_sensors.py b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/utils/fn_6254_dn_f_sensors.py new file mode 100755 index 000000000000..40e23ef01b7e --- /dev/null +++ b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/utils/fn_6254_dn_f_sensors.py @@ -0,0 +1,141 @@ +#!/usr/bin/python + +import os +import sys +import logging + +FAN_NUM = 5 +sensors_path = '/sys/bus/i2c/devices/5-0070/' +sensors_nodes = {'fan_rpm': ['_inner_rpm', '_outer_rpm'], + 'fan_vol': ['ADC8_vol', 'ADC7_vol','ADC6_vol', 'ADC5_vol','ADC4_vol', 'ADC3_vol'], + 'temp':['lm75_49_temp', 'lm75_48_temp', 'SA56004_local_temp','SA56004_remote_temp']} +sensors_type = {'fan_rpm': ['Inner RPM', 'Outer RPM'], + 'fan_vol': ['P0.2', 'P0.6','P0.1', 'P1.5','P0.7', 'P1.6'], + 'temp':['lm75_49_temp', 'lm75_48_temp', 'SA56004_local_temp','SA56004_remote_temp']} + +# Get sysfs attribute +def get_attr_value(attr_path): + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip('\r\n') + fd.close() + return retval + +def get_fan_status(number): + attr_value = get_attr_value(sensors_path + "fan" + str(number+1) + "_present") + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + + if(attr_value == 0): + string = "Connect" + else: + string = "Disconnect" + return string + +def get_fan_alert(number): + attr_value = get_attr_value(sensors_path + "fan" + str(number+1) + "_status_alert") + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + + if(attr_value == 0): + string = "Normal" + else: + string = "Abnormal" + return string + +def get_fan_inner_rpm(number): + return get_attr_value(sensors_path + "fan" + str(number+1) + "_inner_rpm") + +def get_fan_outer_rpm(number): + return get_attr_value(sensors_path + "fan" + str(number+1) + "_outer_rpm") + +def get_fan(): + for i in range(0,FAN_NUM): + print " " + #status + string = get_fan_status(i) + print "FAN " + str(i+1) + ":" + ' ' + string + if string=='Disconnect': + continue + + #alert + string = get_fan_alert(i) + print " Status:"+ ' ' + string + + #inner rpm + string = get_fan_inner_rpm(i) + print " Inner RPM:"+ string.rjust(10) + ' RPM' + + #outer rpm + string = get_fan_outer_rpm(i) + print " Outer RPM:"+ string.rjust(10) + ' RPM' + + return + +def get_hwmon(): + print " " + string = get_attr_value(sensors_path + "lm75_48_temp") + print "Sensor A: " + string + " C" + + string = get_attr_value(sensors_path + "lm75_49_temp") + print "Sensor B: " + string + " C" + + return + +def get_voltage(): + print " " + nodes = sensors_nodes['fan_vol'] + types = sensors_type['fan_vol'] + for i in range(0,len(nodes)): + string = get_attr_value(sensors_path + nodes[i]) + print types[i] + ': ' + string + " V" + + return + +def init_fan(): + return + +def main(): + """ + Usage: %(scriptName)s command object + + command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + set : change board setting with fan|led|sfp + """ + + if len(sys.argv)<2: + print main.__doc__ + + for arg in sys.argv[1:]: + if arg == 'fan_init': + init_fan() + elif arg == 'get_sensors': + ver = get_attr_value(sensors_path + "fb_hw_version") + print 'HW Version: ' + ver + ver = get_attr_value(sensors_path + "fb_fw_version") + print 'SW Version: ' + ver + get_fan() + get_hwmon() + get_voltage() + elif arg == 'fan_set': + if len(sys.argv[1:])<1: + print main.__doc__ + else: + set_fan(sys.argv[1:]) + return + else: + print main.__doc__ + +if __name__ == "__main__": + main() diff --git a/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/utils/pegatron_fn_6254_dn_f_util.py b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/utils/pegatron_fn_6254_dn_f_util.py new file mode 100755 index 000000000000..55e6114b11c8 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-pegatron/fn-6254-dn-f/utils/pegatron_fn_6254_dn_f_util.py @@ -0,0 +1,233 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Pegatron, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import sys, getopt +import logging +import os +import commands +import threading + +DEBUG = False + +SFP_MAX_NUM = 48 +TOTAL_PORT_NUM = 54 +CPLDA_SFP_NUM = 24 +CPLDB_SFP_NUM = 12 +CPLDC_SFP_NUM = 18 + +kernel_module = ['i2c_dev', 'i2c-mux-pca954x force_deselect_on_exit=1', 'at24', 'pegatron_fn_6254_dn_f_cpld', 'pegatron_hwmon_mcu', 'pegatron_fn_6254_dn_f_sfp'] +moduleID = ['pca9544', 'pca9544', '24c02', 'pega_hwmon_mcu', 'fn_6254_dn_f_cpld', 'fn_6254_dn_f_cpld', 'fn_6254_dn_f_cpld', 'fn_6254_dn_f_sfpA', 'fn_6254_dn_f_sfpB', 'fn_6254_dn_f_sfpC'] +i2c_check_node = ['i2c-0', 'i2c-1'] +uninstall_check_node = ['-0072', '-0073'] +device_address = ['0x72', '0x73', '0x54', '0x70', '0x74', '0x75', '0x76', '0x50', '0x50', '0x50'] +device_node= ['i2c-2', 'i2c-6', 'i2c-4', 'i2c-5', 'i2c-6', 'i2c-7', 'i2c-8', 'i2c-6', 'i2c-7', 'i2c-8'] + +i2c_prefix = '/sys/bus/i2c/devices/' +cpld_bus = ['6-0074', '7-0075', '8-0076'] +led_nodes = ['sys_led', 'pwr_led', 'loc_led', 'fan_led', "cpld_allled_ctrl", "serial_led_enable"] + +def dbg_print(string): + if DEBUG == True: + print string + return + +def do_cmd(cmd, show): + logging.info('Run :' + cmd) + status, output = commands.getstatusoutput(cmd) + dbg_print(cmd + "with result:" + str(status)) + dbg_print("output:" + output) + if status: + logging.info('Failed :' + cmd) + if show: + print('Failed :' + cmd) + return status, output + +def install_driver(): + status, output = do_cmd("depmod -a", 1) + + for i in range(0, len(kernel_module)): + status, output = do_cmd("modprobe " + kernel_module[i], 1) + if status: + return status + + return + +def check_device_position(num): + for i in range(0, len(i2c_check_node)): + status, output = do_cmd("echo " + moduleID[num] + " " + device_address[num] + " > " + i2c_prefix + i2c_check_node[i] + "/new_device", 0) + status, output = do_cmd("ls " + i2c_prefix + device_node[num], 0) + device_node[num] = i2c_check_node[i] + + if status: + status, output = do_cmd("echo " + device_address[num] + " > " + i2c_prefix + i2c_check_node[i] + "/delete_device", 0) + else: + return + + return + +def install_device(): + for i in range(0, len(moduleID)): + if moduleID[i] == "pca9544": + check_device_position(i) + else: + status, output = do_cmd("echo " + moduleID[i] + " " + device_address[i] + " > " + i2c_prefix + device_node[i] + "/new_device", 1) + + return + +def check_driver(): + for i in range(0, len(kernel_module)): + status, output = do_cmd("lsmod | grep " + kernel_module[i], 0) + if status: + status, output = do_cmd("modprobe " + kernel_module[i], 1) + + return + +def do_install(): + status, output = do_cmd("depmod -a", 1) + + check_driver() + install_device() + + return + +def do_uninstall(): + for i in range(0, len(kernel_module)): + status, output = do_cmd("modprobe -rq " + kernel_module[i], 0) + + for i in range(0, len(moduleID)): + if moduleID[i] == "pca9544": + for node in range(0, len(i2c_check_node)): + status, output = do_cmd("ls " + i2c_prefix + str(node) + uninstall_check_node[i], 0) + if not status: + status, output = do_cmd("echo " + device_address[i] + " > " + i2c_prefix + i2c_check_node[node] + "/delete_device", 0) + + else: + status, output = do_cmd("echo " + device_address[i] + " > " + i2c_prefix + device_node[i] + "/delete_device", 0) + + return + +led_command = {'sys_led': {'green':'0', 'amber':'1', 'off':'2', 'blink_green':'3', 'blink_amber':'4'}, + 'pwr_led': {'green':'0', 'amber':'1', 'off':'2', 'blink_green':'3', 'blink_amber':'4'}, + 'loc_led': {'on':'0', 'off':'1', 'blink':'2'}, + 'fan_led': {'green':'0', 'amber':'1', 'off':'2', 'blink_green':'3', 'blink_amber':'4'}, + 'cpld_allled_ctrl': {'off':'0', 'mix':'1', 'amber':'2', 'normal':'3'}, + 'serial_led_enable': {'disable':'0', 'enable':'1'}} + +def set_led(args): + """ + Usage: %(scriptName)s set led object command + + object: + sys_led : set SYS led [command: off|green|amber|blink_green|blink_amber] + pwr_led : set PWR led [command: off|green|amber|blink_green|blink_amber] + loc_led : set LOCATOR led [command: off|on|blink] + fan_led : set FAN led [command: off|green|amber|blink_green|blink_amber] + """ + if args[0] not in led_command: + print set_led.__doc__ + sys.exit(0) + + for i in range(0,len(led_nodes)): + if args[0] == led_nodes[i]: + node = i2c_prefix + cpld_bus[1] + '/'+ led_nodes[i] + + command = led_command[args[0]] + data = command[args[1]] + + status, output = do_cmd("echo "+ str(data) + " > "+ node, 1) + + return + +def set_device(args): + """ + Usage: %(scriptName)s command object + + command: + led : set status led sys_led|pwr_led|loc_led|mst_led|fan_led|digit_led + """ + + if args[0] == 'led': + set_led(args[1:]) + return + else: + print set_device.__doc__ + + return + +device_init = {'led': [['led', 'sys_led', 'green'], ['led', 'pwr_led', 'green'], ['led', 'fan_led', 'green'], ['led', 'cpld_allled_ctrl', 'normal'], ['led', 'serial_led_enable', 'enable']]} + +def pega_init(): + #set led + for i in range(0,len(device_init['led'])): + set_device(device_init['led'][i]) + + #set tx_disable + for x in range(0, SFP_MAX_NUM): + if x < CPLDB_SFP_NUM: + bus = cpld_bus[1] + elif x < CPLDB_SFP_NUM + CPLDA_SFP_NUM: + bus = cpld_bus[0] + else: + bus = cpld_bus[2] + + nodes = i2c_prefix + bus + '/sfp' + str(x+1) + '_tx_disable' + dbg_print("SFP_TX_DISABLE NODES: " + nodes) + status, output = do_cmd("echo 0 > "+ nodes, 1) + + for x in range(SFP_MAX_NUM, TOTAL_PORT_NUM): + nodes = i2c_prefix + cpld_bus[2] + '/sfp' + str(x+1) + '_reset' + dbg_print("SFP_RESET NODES: " + nodes) + status, output = do_cmd("echo 3 > "+ nodes, 1) + + return + +def main(): + """ + Usage: %(scriptName)s command object + + command: + install : install drivers and generate related sysfs nodes + uninstall : uninstall drivers and remove related sysfs nodes + set : change board setting [led] + debug : debug info [on/off] + """ + + if len(sys.argv)<2: + print main.__doc__ + + for arg in sys.argv[1:]: + if arg == 'install': + do_install() + pega_init() + elif arg == 'uninstall': + do_uninstall() + elif arg == 'set': + if len(sys.argv[2:])<1: + print main.__doc__ + else: + set_device(sys.argv[2:]) + return + elif arg == 'debug': + if sys.argv[2] == 'on': + DEBUG = True + else: + DEBUG = False + else: + print main.__doc__ + +if __name__ == "__main__": + main() diff --git a/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_porsche_sfp.c b/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_porsche_sfp.c index 5d5d64b15e1a..9e4b8dbb975d 100644 --- a/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_porsche_sfp.c +++ b/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_porsche_sfp.c @@ -62,9 +62,9 @@ enum cpld_croups { cpld_group_a, cpld_group_b, cpld_group_c}; static const unsigned short normal_i2c[] = { SFP_EEPROM_A0_ADDR, SFP_EEPROM_A2_ADDR, I2C_CLIENT_END }; -static char *SFP_CPLD_GROUPA_MAPPING[CPLDA_SFP_NUM][16]={0}; -static char *SFP_CPLD_GROUPB_MAPPING[CPLDB_SFP_NUM][16]={0}; -static char *SFP_CPLD_GROUPC_MAPPING[CPLDC_SFP_NUM][16]={0}; +static char SFP_CPLD_GROUPA_MAPPING[CPLDA_SFP_NUM][16]={0}; +static char SFP_CPLD_GROUPB_MAPPING[CPLDB_SFP_NUM][16]={0}; +static char SFP_CPLD_GROUPC_MAPPING[CPLDC_SFP_NUM][16]={0}; /* * This parameter is to help this driver avoid blocking other drivers out diff --git a/platform/nephos/sonic-platform-modules-pegatron/porsche/utils/pegatron_porsche_util.py b/platform/nephos/sonic-platform-modules-pegatron/porsche/utils/pegatron_porsche_util.py index 16662081d0cb..d46bb110b386 100755 --- a/platform/nephos/sonic-platform-modules-pegatron/porsche/utils/pegatron_porsche_util.py +++ b/platform/nephos/sonic-platform-modules-pegatron/porsche/utils/pegatron_porsche_util.py @@ -24,13 +24,15 @@ DEBUG = False SFP_MAX_NUM = 48 +MAX_PORT = 54 CPLDA_SFP_NUM = 24 CPLDB_SFP_NUM = 12 CPLDC_SFP_NUM = 18 kernel_module = ['i2c_dev', 'i2c-mux-pca954x force_deselect_on_exit=1', 'at24', 'pegatron_porsche_cpld', 'pegatron_hwmon_mcu', 'pegatron_porsche_sfp'] -moduleID = ['pca9544', 'pca9544', '24c02', 'porsche_hwmon_mcu', 'porsche_cpld', 'porsche_cpld', 'porsche_cpld', 'porsche_sfpA', 'porsche_sfpB', 'porsche_sfpC'] +moduleID = ['pca9544', 'pca9544', '24c02', 'pega_hwmon_mcu', 'porsche_cpld', 'porsche_cpld', 'porsche_cpld', 'porsche_sfpA', 'porsche_sfpB', 'porsche_sfpC'] i2c_check_node = ['i2c-0', 'i2c-1'] +uninstall_check_node = ['-0072', '-0073'] device_address = ['0x72', '0x73', '0x54', '0x70', '0x74', '0x75', '0x76', '0x50', '0x50', '0x50'] device_node= ['i2c-2', 'i2c-6', 'i2c-4', 'i2c-5', 'i2c-6', 'i2c-7', 'i2c-8', 'i2c-6', 'i2c-7', 'i2c-8'] @@ -54,6 +56,16 @@ def do_cmd(cmd, show): print('Failed :' + cmd) return status, output +def install_driver(): + status, output = do_cmd("depmod -a", 1) + + for i in range(0, len(kernel_module)): + status, output = do_cmd("modprobe " + kernel_module[i], 1) + if status: + return status + + return + def check_device_position(num): for i in range(0, len(i2c_check_node)): status, output = do_cmd("echo " + moduleID[num] + " " + device_address[num] + " > " + i2c_prefix + i2c_check_node[i] + "/new_device", 0) @@ -94,10 +106,17 @@ def do_install(): def do_uninstall(): for i in range(0, len(kernel_module)): - status, output = do_cmd("modprobe -r " + kernel_module[i], 1) + status, output = do_cmd("modprobe -rq " + kernel_module[i], 0) for i in range(0, len(moduleID)): - status, output = do_cmd("echo " + device_address[i] + " > " + i2c_prefix + i2c_check_node[i] + "/delete_device", 0) + if moduleID[i] == "pca9544": + for node in range(0, len(i2c_check_node)): + status, output = do_cmd("ls " + i2c_prefix + str(node) + uninstall_check_node[i], 0) + if not status: + status, output = do_cmd("echo " + device_address[i] + " > " + i2c_prefix + i2c_check_node[node] + "/delete_device", 0) + + else: + status, output = do_cmd("echo " + device_address[i] + " > " + i2c_prefix + device_node[i] + "/delete_device", 0) return @@ -169,6 +188,10 @@ def pega_init(): dbg_print("SFP_TX_DISABLE NODES: " + nodes) status, output = do_cmd("echo 0 > "+ nodes, 1) + for x in range(SFP_MAX_NUM, MAX_PORT): + nodes = i2c_prefix + bus + '/sfp' + str(x+1) + '_reset' + status, output = do_cmd("echo 1 > "+ nodes, 1) + return def main(): @@ -177,7 +200,7 @@ def main(): command: install : install drivers and generate related sysfs nodes - clean : uninstall drivers and remove related sysfs nodes + uninstall : uninstall drivers and remove related sysfs nodes set : change board setting [led] debug : debug info [on/off] """