Revert "[Ragile]: Add new centec platform ra-b6010 (#14819)"

This reverts commit 75062436e8.
This commit is contained in:
Guohan Lu 2023-09-01 22:43:18 -07:00
parent f6897bb585
commit 3bdfdd95ea
142 changed files with 2 additions and 34567 deletions

View File

@ -1,868 +0,0 @@
{
"macleds" : {
"polarity" : 1,
"freq" : 2500,
"interval" : 50000000,
"maps" : [
{
"port_id" : 0,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port1/brightness"
},
{
"port_id" : 1,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port2/brightness"
},
{
"port_id" : 2,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port3/brightness"
},
{
"port_id" : 3,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port4/brightness"
},
{
"port_id" : 4,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port5/brightness"
},
{
"port_id" : 5,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port6/brightness"
},
{
"port_id" : 6,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port7/brightness"
},
{
"port_id" : 7,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port8/brightness"
},
{
"port_id" : 16,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port9/brightness"
},
{
"port_id" : 17,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port10/brightness"
},
{
"port_id" : 18,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port11/brightness"
},
{
"port_id" : 19,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port12/brightness"
},
{
"port_id" : 20,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port13/brightness"
},
{
"port_id" : 21,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port14/brightness"
},
{
"port_id" : 22,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port15/brightness"
},
{
"port_id" : 23,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port16/brightness"
},
{
"port_id" : 8,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port17/brightness"
},
{
"port_id" : 9,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port18/brightness"
},
{
"port_id" : 10,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port19/brightness"
},
{
"port_id" : 11,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port20/brightness"
},
{
"port_id" : 32,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port21/brightness"
},
{
"port_id" : 33,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port22/brightness"
},
{
"port_id" : 34,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port23/brightness"
},
{
"port_id" : 35,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port24/brightness"
},
{
"port_id" : 36,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port25/brightness"
},
{
"port_id" : 37,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port26/brightness"
},
{
"port_id" : 38,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port27/brightness"
},
{
"port_id" : 39,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port28/brightness"
},
{
"port_id" : 40,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port29/brightness"
},
{
"port_id" : 41,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port30/brightness"
},
{
"port_id" : 42,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port31/brightness"
},
{
"port_id" : 43,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port32/brightness"
},
{
"port_id" : 24,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port33/brightness"
},
{
"port_id" : 25,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port34/brightness"
},
{
"port_id" : 26,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port35/brightness"
},
{
"port_id" : 27,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port36/brightness"
},
{
"port_id" : 48,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port37/brightness"
},
{
"port_id" : 49,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port38/brightness"
},
{
"port_id" : 50,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port39/brightness"
},
{
"port_id" : 51,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port40/brightness"
},
{
"port_id" : 52,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port41/brightness"
},
{
"port_id" : 53,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port42/brightness"
},
{
"port_id" : 54,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port43/brightness"
},
{
"port_id" : 55,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port44/brightness"
},
{
"port_id" : 56,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port45/brightness"
},
{
"port_id" : 57,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port46/brightness"
},
{
"port_id" : 58,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port47/brightness"
},
{
"port_id" : 59,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port48/brightness"
},
{
"port_id" : 12,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port49/brightness"
},
{
"port_id" : 13,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port50/brightness"
},
{
"port_id" : 14,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port51/brightness"
},
{
"port_id" : 15,
"lchip" : 0,
"ctl_id" : 0,
"mode" : "LED_MODE_1_RXLNK_BIACT",
"fixed" : 0,
"sysfs_path" : "/sys/class/leds/port52/brightness"
}
]
},
"phys" : [
{
"macid" : 0,
"busid" : 0,
"addr" : 0,
"base_port": 1,
"last_port": 4
},
{
"macid" : 1,
"busid" : 0,
"addr" : 1,
"base_port": 1,
"last_port": 4
},
{
"macid" : 2,
"busid" : 0,
"addr" : 2,
"base_port": 1,
"last_port": 4
},
{
"macid" : 3,
"busid" : 0,
"addr" : 3,
"base_port": 1,
"last_port": 4
},
{
"macid" : 4,
"busid" : 0,
"addr" : 4,
"base_port": 1,
"last_port": 4
},
{
"macid" : 5,
"busid" : 0,
"addr" : 5,
"base_port": 1,
"last_port": 4
},
{
"macid" : 6,
"busid" : 0,
"addr" : 6,
"base_port": 1,
"last_port": 4
},
{
"macid" : 7,
"busid" : 0,
"addr" : 7,
"base_port": 1,
"last_port": 4
},
{
"macid" : 16,
"busid" : 0,
"addr" : 8,
"base_port": 1,
"last_port": 4
},
{
"macid" : 17,
"busid" : 0,
"addr" : 9,
"base_port": 1,
"last_port": 4
},
{
"macid" : 18,
"busid" : 0,
"addr" : 10,
"base_port": 1,
"last_port": 4
},
{
"macid" : 19,
"busid" : 0,
"addr" : 11,
"base_port": 1,
"last_port": 4
},
{
"macid" : 20,
"busid" : 0,
"addr" : 12,
"base_port": 1,
"last_port": 4
},
{
"macid" : 21,
"busid" : 0,
"addr" : 13,
"base_port": 1,
"last_port": 4
},
{
"macid" : 22,
"busid" : 0,
"addr" : 14,
"base_port": 1,
"last_port": 4
},
{
"macid" : 23,
"busid" : 0,
"addr" : 15,
"base_port": 1,
"last_port": 4
},
{
"macid" : 8,
"busid" : 0,
"addr" : 16,
"base_port": 1,
"last_port": 4
},
{
"macid" : 9,
"busid" : 0,
"addr" : 17,
"base_port": 1,
"last_port": 4
},
{
"macid" : 10,
"busid" : 0,
"addr" : 18,
"base_port": 1,
"last_port": 4
},
{
"macid" : 11,
"busid" : 0,
"addr" : 19,
"base_port": 1,
"last_port": 4
},
{
"macid" : 32,
"busid" : 0,
"addr" : 20,
"base_port": 1,
"last_port": 4
},
{
"macid" : 33,
"busid" : 0,
"addr" : 21,
"base_port": 1,
"last_port": 4
},
{
"macid" : 34,
"busid" : 0,
"addr" : 22,
"base_port": 1,
"last_port": 4
},
{
"macid" : 35,
"busid" : 0,
"addr" : 23,
"base_port": 1,
"last_port": 4
},
{
"macid" : 36,
"busid" : 1,
"addr" : 0,
"base_port": 1,
"last_port": 4
},
{
"macid" : 37,
"busid" : 1,
"addr" : 1,
"base_port": 1,
"last_port": 4
},
{
"macid" : 38,
"busid" : 1,
"addr" : 2,
"base_port": 1,
"last_port": 4
},
{
"macid" : 39,
"busid" : 1,
"addr" : 3,
"base_port": 1,
"last_port": 4
},
{
"macid" : 40,
"busid" : 1,
"addr" : 4,
"base_port": 1,
"last_port": 4
},
{
"macid" : 41,
"busid" : 1,
"addr" : 5,
"base_port": 1,
"last_port": 4
},
{
"macid" : 42,
"busid" : 1,
"addr" : 6,
"base_port": 1,
"last_port": 4
},
{
"macid" : 43,
"busid" : 1,
"addr" : 7,
"base_port": 1,
"last_port": 4
},
{
"macid" : 24,
"busid" : 1,
"addr" : 8,
"base_port": 1,
"last_port": 4
},
{
"macid" : 25,
"busid" : 1,
"addr" : 9,
"base_port": 1,
"last_port": 4
},
{
"macid" : 26,
"busid" : 1,
"addr" : 10,
"base_port": 1,
"last_port": 4
},
{
"macid" : 27,
"busid" : 1,
"addr" : 11,
"base_port": 1,
"last_port": 4
},
{
"macid" : 48,
"busid" : 1,
"addr" : 12,
"base_port": 1,
"last_port": 4
},
{
"macid" : 49,
"busid" : 1,
"addr" : 13,
"base_port": 1,
"last_port": 4
},
{
"macid" : 50,
"busid" : 1,
"addr" : 14,
"base_port": 1,
"last_port": 4
},
{
"macid" : 51,
"busid" : 1,
"addr" : 15,
"base_port": 1,
"last_port": 4
},
{
"macid" : 52,
"busid" : 1,
"addr" : 16,
"base_port": 1,
"last_port": 4
},
{
"macid" : 53,
"busid" : 1,
"addr" : 17,
"base_port": 1,
"last_port": 4
},
{
"macid" : 54,
"busid" : 1,
"addr" : 18,
"base_port": 1,
"last_port": 4
},
{
"macid" : 55,
"busid" : 1,
"addr" : 19,
"base_port": 1,
"last_port": 4
},
{
"macid" : 56,
"busid" : 1,
"addr" : 20,
"base_port": 1,
"last_port": 4
},
{
"macid" : 57,
"busid" : 1,
"addr" : 21,
"base_port": 1,
"last_port": 4
},
{
"macid" : 58,
"busid" : 1,
"addr" : 22,
"base_port": 1,
"last_port": 4
},
{
"macid" : 59,
"busid" : 1,
"addr" : 23,
"base_port": 1,
"last_port": 4
}
],
"ffe" : {
"board_material" : "BOARD_MATERIAL_M4",
"config" : [
{
"serdes_id" : [0],
"is_dac" : 0,
"speed" : [1000],
"mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE",
"cfg" : [0, 255, 10, 0]
},
{
"serdes_id" : [1],
"is_dac" : 0,
"speed" : [1000],
"mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE",
"cfg" : [0, 240, 10, 0]
},
{
"serdes_id" : [2],
"is_dac" : 0,
"speed" : [1000],
"mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE",
"cfg" : [0, 230, 10, 0]
},
{
"serdes_id" : [3],
"is_dac" : 0,
"speed" : [1000],
"mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE",
"cfg" : [0, 220, 7, 0]
},
{
"serdes_id" : [4],
"is_dac" : 0,
"speed" : [1000],
"mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE",
"cfg" : [0, 220, 8, 0]
},
{
"serdes_id" : [5],
"is_dac" : 0,
"speed" : [1000],
"mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE",
"cfg" : [0, 210, 6, 0]
},
{
"serdes_id" : [6],
"is_dac" : 0,
"speed" : [1000],
"mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE",
"cfg" : [0, 180, 6, 0]
},
{
"serdes_id" : [7],
"is_dac" : 0,
"speed" : [1000],
"mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE",
"cfg" : [0, 180, 5, 0]
},
{
"serdes_id" : [8],
"is_dac" : 0,
"speed" : [1000],
"mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE",
"cfg" : [2, 160, 4, 0]
},
{
"serdes_id" : [9],
"is_dac" : 0,
"speed" : [1000],
"mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE",
"cfg" : [2, 160, 4, 0]
},
{
"serdes_id" : [10],
"is_dac" : 0,
"speed" : [1000],
"mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE",
"cfg" : [3, 140, 9, 0]
},
{
"serdes_id" : [11],
"is_dac" : 0,
"speed" : [1000],
"mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE",
"cfg" : [3, 140, 5, 0]
},
{
"serdes_id" : [12, 13, 14, 15],
"is_dac" : 0,
"speed" : [10000],
"mode" : "CTC_CHIP_SERDES_FFE_MODE_DEFINE",
"cfg" : [3, 94, 15, 0]
}
]
},
"ctle" : {
"config" : [
{
"serdes_id" : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
"auto-en" : 0,
"cfg" : [6, 14, 2]
}
]
}
}

View File

@ -1,96 +0,0 @@
#----------------- SDK Feature Support --------------
[MPLS_SUPPORT] = 1;
[APS_SUPPORT] = 1;
[OAM_SUPPORT] = 1;
[PTP_SUPPORT] = 0;
[SYNCE_SUPPORT] = 0;
[STACKING_SUPPORT] = 1;
[BPE_SUPPORT] = 0;
[IPFIX_SUPPORT] = 1;
[MONITOR_SUPPORT] = 1;
[OVERLAY_SUPPORT] = 1;
[EFD_SUPPORT] = 1;
[FCOE_SUPPORT] = 0;
[TRILL_SUPPORT] = 0;
[WLAN_SUPPORT] = 1;
[NPM_SUPPORT] = 1;
[DOT1AE_SUPPORT] = 1;
#----------------- Chip Init Parameter --------------
#Local chip number and global chip id
[Local chip_num] = 1
[Local chip0] = 0
[Local chip1] = 1
#Cut through mode 0: Disable; 1:10/40/100G; 2:1/10/100G; 3:1/10/40G; other:Flex, refer to CUT_THROUGH_BITMAP
[CUT_THROUGH_SPEED] = 0
#Flex cut through mode, speed enable by bitmap, refer to ctc_port_speed_t, Notice: 10M/100M/1G treat as the same speed
[CUT_THROUGH_BITMAP] = 0
#Network cpu port
[CPU_NETWORK_PORT_EN] = 0
[CPU_NETWORK_PORT_ID] = 47
#Enable parity error and multi-bit ecc recover
[ECC_RECOVER_EN] = 0
[TCAM_SCAN_EN] = 0
#----------------- Interrupt Init Parameter --------------
#0: pin, 1: msi
[Interrupt_mode] = 0
[IRQ] = 69
#----------------- NextHop Init Parameter --------------
#0: SDK work in pizzbox (single chip system), 1: SDK work in multi-chip system
[Nexthop Edit Mode] = 0
[External Nexthop Number] = 16384
[MPLS Tunnel Number] = 1024
#----------------- L2 Init Parameter --------------
[FDB Hw Learning] = 1
[Logic Port Num] = 1024
#0: 128 instance per port, 1: 64 instance per port, 2: 32 instance per port
[STP MODE] = 0
[MAX_FID_NUM] = 5120
#----------------- Stats Init Parameter --------------
[STATS_PORT_EN] = 0
[STATS_ECMP_EN] = 0
#----------------- BPE Init Parameter --------------
[BPE_BR_PORT_EXTENDER_EN] = 0
[BPE_BR_UC_MAX_ECID] = 1024
[BPE_BR_MC_MAX_ECID] = 4096
[BPE_BR_PORT_BASE] = 0
#----------------- Ipuc Init Parameter --------------
#0: tcam use prefix 16; 1: tcam use prefix 8
[IPUC_TCAM_PREFIX_8] = 1
#----------------- QoS Init Parameter --------------
#QoS policer number support 1K/2K/4K/8K, default 4K
[QOS_POLICER_NUM] = 4096
#QoS port queue number support 16/8/8 BPE/4 BPE,
#When resrc_profile.cfg exist, queue number valid,
#Default 8 queue mode
#8 queue = 8
#16 queue = 16
#4 queue BPE = 17
#8 queue BPE = 18
[QOS_PORT_QUEUE_NUM] = 8
#QoS port extend queue number support 0/4, default 0
[QOS_PORT_EXT_QUEUE_NUM] = 0
#QoS CPU reason queue number support 128/64/32, default 128
[QOS_CPU_QUEUE_NUM] = 128
[QOS_INGRESS_VLAN_POLICER_NUM] = 0
[QOS_EGRESS_VLAN_POLICER_NUM] = 0
[QOS_POLICER_MERGE_MODE] = 0
#QOS service queue mode, default 0,0:logic scr port + dstport enq 1:service id + dstport enq
[QOS_SERVICE_QUEUE_MODE] = 0
#Global enable logic dst port + dstport enq
[QOS_SERVICE_QUEUE_EGRESS_EN] = 0
#----------------- Stacking Init Parameter --------------
#0: normal mode; 1: spine-leaf mode
[FABRIC MODE] = 0
[STACKING VERSION] = 1

View File

@ -1,281 +0,0 @@
#Generated by 'CTC DataPath Tools' on Fri Dec 18 19:15:31 2020
#Version 1.0, Supported by TsingMa SDK
#SERDES_MODE : 0-NONE, 1-XFI, 2-SGMII, 3-Not Support, 4-QSGMII, 5-XAUI, 6-DXAUI, 7-XLG, 8-CG, 9-SGMII2G5
# 10-USXGMII-S, 11-USXGMII-M2G5, 12-USXGMII-M5G, 13-XXVG, 14-LG, 15-100BASE-FX
#SERDES_RX_POLY: 0-Normal, 1-Inverse
#SERDES_SWITCH : 0-Not Support Dynamic Switch, 1-Support Dynamic Switch
[WLAN_ENABLE] = 1
[DOT1AE_ENABLE] = 1
[CORE_PLLA] = 600
#{
[SERDES_ITEM]
#repeat 32 step 6
[SERDES_ID] = 0
[SERDES_MODE] = 4
[SERDES_RX_POLY] = 1
[SERDES_TX_POLY] = 1
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 1
[SERDES_MODE] = 4
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 2
[SERDES_MODE] = 4
[SERDES_RX_POLY] = 1
[SERDES_TX_POLY] = 1
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 3
[SERDES_MODE] = 4
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 4
[SERDES_MODE] = 4
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 5
[SERDES_MODE] = 4
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 6
[SERDES_MODE] = 4
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 7
[SERDES_MODE] = 4
[SERDES_RX_POLY] = 1
[SERDES_TX_POLY] = 1
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 8
[SERDES_MODE] = 4
[SERDES_RX_POLY] = 1
[SERDES_TX_POLY] = 1
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 9
[SERDES_MODE] = 4
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 10
[SERDES_MODE] = 4
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 11
[SERDES_MODE] = 4
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 12
[SERDES_MODE] = 1
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 1
[SERDES_GROUP] = 0
[SERDES_ID] = 13
[SERDES_MODE] = 1
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 1
[SERDES_GROUP] = 0
[SERDES_ID] = 14
[SERDES_MODE] = 1
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 1
[SERDES_GROUP] = 0
[SERDES_ID] = 15
[SERDES_MODE] = 1
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 1
[SERDES_GROUP] = 0
[SERDES_ID] = 16
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 17
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 18
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 19
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 20
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 21
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 22
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 23
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 24
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 25
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 26
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 1
[SERDES_ID] = 27
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 1
[SERDES_ID] = 28
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 29
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 0
[SERDES_ID] = 30
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 1
[SERDES_ID] = 31
[SERDES_MODE] = 3
[SERDES_RX_POLY] = 0
[SERDES_TX_POLY] = 0
[SERDES_SWITCH] = 0
[SERDES_GROUP] = 1
#repeat end
#}
#[SERDES_TO_LPORT]
#{
# | QSGMII/USXGMII-M2G5 | USXGMII-M5G | USXGMII-S | 100BASE-FX | SGMII/SGMII2G5/XFI | XAUI/DXAUI | XLG | XXVG | LG | CG
#---------|---------------------|-------------|-----------|------------|--------------------|------------|-----|------|----|---
#serdes 0 |0 /1 /2 /3 |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 1 |4 /5 /6 /7 |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 2 |16/17/18/19 |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 3 |20/21/22/23 |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 4 |8 /9 /10/11 |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 5 |32/33/34/35 |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 6 |36/37/38/39 |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 7 |40/41/42/43 |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 8 |24/25/26/27 |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 9 |48/49/50/51 |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 10|52/53/54/55 |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 11|56/57/58/59 |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 12|NA |NA |NA |12 |12 |12 |12 |NA |NA |NA
#serdes 13|NA |NA |NA |13 |13 |12 |12 |NA |NA |NA
#serdes 14|NA |NA |NA |14 |14 |12 |12 |NA |NA |NA
#serdes 15|NA |NA |NA |15 |15 |12 |12 |NA |NA |NA
#serdes 16|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 17|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 18|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 19|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 20|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 21|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 22|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 23|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 24|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 25|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 26|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 27|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 28|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 29|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 30|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#serdes 31|NA |NA |NA |NA |NA |NA |NA |NA |NA |NA
#}

View File

@ -1,198 +0,0 @@
#######################PHY_MAPPING_48+4#######################
#{
[PHY_MAPPING_ITEM]
[API_PORT] = 0
[PHY_ADDR] = 0
[MDIO_BUS] = 0
[API_PORT] = 1
[PHY_ADDR] = 1
[MDIO_BUS] = 0
[API_PORT] = 2
[PHY_ADDR] = 2
[MDIO_BUS] = 0
[API_PORT] = 3
[PHY_ADDR] = 3
[MDIO_BUS] = 0
[API_PORT] = 4
[PHY_ADDR] = 4
[MDIO_BUS] = 0
[API_PORT] = 5
[PHY_ADDR] = 5
[MDIO_BUS] = 0
[API_PORT] = 6
[PHY_ADDR] = 6
[MDIO_BUS] = 0
[API_PORT] = 7
[PHY_ADDR] = 7
[MDIO_BUS] = 0
[API_PORT] = 16
[PHY_ADDR] = 8
[MDIO_BUS] = 0
[API_PORT] = 17
[PHY_ADDR] = 9
[MDIO_BUS] = 0
[API_PORT] = 18
[PHY_ADDR] = 10
[MDIO_BUS] = 0
[API_PORT] = 19
[PHY_ADDR] = 11
[MDIO_BUS] = 0
[API_PORT] = 20
[PHY_ADDR] = 12
[MDIO_BUS] = 0
[API_PORT] = 21
[PHY_ADDR] = 13
[MDIO_BUS] = 0
[API_PORT] = 22
[PHY_ADDR] = 14
[MDIO_BUS] = 0
[API_PORT] = 23
[PHY_ADDR] = 15
[MDIO_BUS] = 0
[API_PORT] = 8
[PHY_ADDR] = 16
[MDIO_BUS] = 0
[API_PORT] = 9
[PHY_ADDR] = 17
[MDIO_BUS] = 0
[API_PORT] = 10
[PHY_ADDR] = 18
[MDIO_BUS] = 0
[API_PORT] = 11
[PHY_ADDR] = 19
[MDIO_BUS] = 0
[API_PORT] = 32
[PHY_ADDR] = 20
[MDIO_BUS] = 0
[API_PORT] = 33
[PHY_ADDR] = 21
[MDIO_BUS] = 0
[API_PORT] = 34
[PHY_ADDR] = 22
[MDIO_BUS] = 0
[API_PORT] = 35
[PHY_ADDR] = 23
[MDIO_BUS] = 0
[API_PORT] = 36
[PHY_ADDR] = 0
[MDIO_BUS] = 1
[API_PORT] = 37
[PHY_ADDR] = 1
[MDIO_BUS] = 1
[API_PORT] = 38
[PHY_ADDR] = 2
[MDIO_BUS] = 1
[API_PORT] = 39
[PHY_ADDR] = 3
[MDIO_BUS] = 1
[API_PORT] = 40
[PHY_ADDR] = 4
[MDIO_BUS] = 1
[API_PORT] = 41
[PHY_ADDR] = 5
[MDIO_BUS] = 1
[API_PORT] = 42
[PHY_ADDR] = 6
[MDIO_BUS] = 1
[API_PORT] = 43
[PHY_ADDR] = 7
[MDIO_BUS] = 1
[API_PORT] = 24
[PHY_ADDR] = 8
[MDIO_BUS] = 1
[API_PORT] = 25
[PHY_ADDR] = 9
[MDIO_BUS] = 1
[API_PORT] = 26
[PHY_ADDR] = 10
[MDIO_BUS] = 1
[API_PORT] = 27
[PHY_ADDR] = 11
[MDIO_BUS] = 1
[API_PORT] = 48
[PHY_ADDR] = 12
[MDIO_BUS] = 1
[API_PORT] = 49
[PHY_ADDR] = 13
[MDIO_BUS] = 1
[API_PORT] = 50
[PHY_ADDR] = 14
[MDIO_BUS] = 1
[API_PORT] = 51
[PHY_ADDR] = 15
[MDIO_BUS] = 1
[API_PORT] = 52
[PHY_ADDR] = 16
[MDIO_BUS] = 1
[API_PORT] = 53
[PHY_ADDR] = 17
[MDIO_BUS] = 1
[API_PORT] = 54
[PHY_ADDR] = 18
[MDIO_BUS] = 1
[API_PORT] = 55
[PHY_ADDR] = 19
[MDIO_BUS] = 1
[API_PORT] = 56
[PHY_ADDR] = 20
[MDIO_BUS] = 1
[API_PORT] = 57
[PHY_ADDR] = 21
[MDIO_BUS] = 1
[API_PORT] = 58
[PHY_ADDR] = 22
[MDIO_BUS] = 1
[API_PORT] = 59
[PHY_ADDR] = 23
[MDIO_BUS] = 1
#}

View File

@ -1,53 +0,0 @@
# name lanes alias index speed admin_status
Ethernet1 0 eth-0-1 1 1000 up
Ethernet2 1 eth-0-2 2 1000 up
Ethernet3 2 eth-0-3 3 1000 up
Ethernet4 3 eth-0-4 4 1000 up
Ethernet5 4 eth-0-5 5 1000 up
Ethernet6 5 eth-0-6 6 1000 up
Ethernet7 6 eth-0-7 7 1000 up
Ethernet8 7 eth-0-8 8 1000 up
Ethernet9 16 eth-0-9 9 1000 up
Ethernet10 17 eth-0-10 10 1000 up
Ethernet11 18 eth-0-11 11 1000 up
Ethernet12 19 eth-0-12 12 1000 up
Ethernet13 20 eth-0-13 13 1000 up
Ethernet14 21 eth-0-14 14 1000 up
Ethernet15 22 eth-0-15 15 1000 up
Ethernet16 23 eth-0-16 16 1000 up
Ethernet17 8 eth-0-17 17 1000 up
Ethernet18 9 eth-0-18 18 1000 up
Ethernet19 10 eth-0-19 19 1000 up
Ethernet20 11 eth-0-20 20 1000 up
Ethernet21 32 eth-0-21 21 1000 up
Ethernet22 33 eth-0-22 22 1000 up
Ethernet23 34 eth-0-23 23 1000 up
Ethernet24 35 eth-0-24 24 1000 up
Ethernet25 36 eth-0-25 25 1000 up
Ethernet26 37 eth-0-26 26 1000 up
Ethernet27 38 eth-0-27 27 1000 up
Ethernet28 39 eth-0-28 28 1000 up
Ethernet29 40 eth-0-29 29 1000 up
Ethernet30 41 eth-0-30 30 1000 up
Ethernet31 42 eth-0-31 31 1000 up
Ethernet32 43 eth-0-32 32 1000 up
Ethernet33 24 eth-0-33 33 1000 up
Ethernet34 25 eth-0-34 34 1000 up
Ethernet35 26 eth-0-35 35 1000 up
Ethernet36 27 eth-0-36 36 1000 up
Ethernet37 48 eth-0-37 37 1000 up
Ethernet38 49 eth-0-38 38 1000 up
Ethernet39 50 eth-0-39 39 1000 up
Ethernet40 51 eth-0-40 40 1000 up
Ethernet41 52 eth-0-41 41 1000 up
Ethernet42 53 eth-0-42 42 1000 up
Ethernet43 54 eth-0-43 43 1000 up
Ethernet44 55 eth-0-44 44 1000 up
Ethernet45 56 eth-0-45 45 1000 up
Ethernet46 57 eth-0-46 46 1000 up
Ethernet47 58 eth-0-47 47 1000 up
Ethernet48 59 eth-0-48 48 1000 up
Ethernet49 12 eth-0-49 49 10000 up
Ethernet50 13 eth-0-50 50 10000 up
Ethernet51 14 eth-0-51 51 10000 up
Ethernet52 15 eth-0-52 52 10000 up

View File

@ -1,4 +0,0 @@
SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/RA-b6010-48gt4x-p-chip-profile.txt
SAI_HW_PORT_PROFILE_ID_CONFIG_FILE=/usr/share/sonic/hwsku/RA-b6010-48gt4x-p-datapath.txt
SAI_PLATFORM_CFG_FILE=/usr/share/sonic/hwsku/RA-b6010-48gt4x-board.json
SAI_PHY_DRIVER_PATH=/usr/share/sonic/hwsku/phy_drv

View File

@ -1,48 +0,0 @@
chip set serdes 0 ffe mode user-define c0 0 c1 255 c2 10 c3 0 c4 0
chip set serdes 1 ffe mode user-define c0 0 c1 240 c2 10 c3 0 c4 0
chip set serdes 2 ffe mode user-define c0 0 c1 230 c2 10 c3 0 c4 0
chip set serdes 3 ffe mode user-define c0 0 c1 220 c2 7 c3 0 c4 0
chip set serdes 4 ffe mode user-define c0 0 c1 220 c2 8 c3 0 c4 0
chip set serdes 5 ffe mode user-define c0 0 c1 210 c2 6 c3 0 c4 0
chip set serdes 6 ffe mode user-define c0 0 c1 180 c2 6 c3 0 c4 0
chip set serdes 7 ffe mode user-define c0 0 c1 180 c2 5 c3 0 c4 0
chip set serdes 8 ffe mode user-define c0 2 c1 160 c2 4 c3 0 c4 0
chip set serdes 9 ffe mode user-define c0 2 c1 160 c2 4 c3 0 c4 0
chip set serdes 10 ffe mode user-define c0 3 c1 140 c2 9 c3 0 c4 0
chip set serdes 11 ffe mode user-define c0 3 c1 140 c2 5 c3 0 c4 0
chip set serdes 12 ffe mode user-define c0 3 c1 94 c2 15 c3 0 c4 0
chip set serdes 13 ffe mode user-define c0 3 c1 94 c2 15 c3 0 c4 0
chip set serdes 14 ffe mode user-define c0 3 c1 94 c2 15 c3 0 c4 0
chip set serdes 15 ffe mode user-define c0 3 c1 94 c2 15 c3 0 c4 0
chip set serdes 0 ctle 6 14 2
chip set serdes 1 ctle 6 14 2
chip set serdes 2 ctle 6 14 2
chip set serdes 3 ctle 6 14 2
chip set serdes 4 ctle 6 14 2
chip set serdes 5 ctle 6 14 2
chip set serdes 6 ctle 6 14 2
chip set serdes 7 ctle 6 14 2
chip set serdes 8 ctle 6 14 2
chip set serdes 9 ctle 6 14 2
chip set serdes 10 ctle 6 14 2
chip set serdes 11 ctle 6 14 2
# rtk eye param, post_amp|main_amp|pre_amp
port 0 phy-attr type 2001 value 0x1c1e00
port 4 phy-attr type 2001 value 0x101600
port 16 phy-attr type 2001 value 0x111500
port 20 phy-attr type 2001 value 0x0e1100
port 8 phy-attr type 2001 value 0x0f1000
port 32 phy-attr type 2001 value 0x0e0f00
port 36 phy-attr type 2001 value 0x0a0a00
port 40 phy-attr type 2001 value 0x0a0900
port 24 phy-attr type 2001 value 0x000c00
port 48 phy-attr type 2001 value 0x000b00
port 52 phy-attr type 2001 value 0x000b00
port 56 phy-attr type 2001 value 0x000a00

View File

@ -1 +0,0 @@
RA-B6010-48GT4X l1

View File

@ -1,9 +0,0 @@
CONSOLE_SPEED=115200
#fix env
config_env(){
dd if=/dev/mtd1 of=env.bin
flashcp -v env.bin /dev/mtd4
}
trap_push "config_env || true"

View File

@ -1,173 +0,0 @@
{
"chassis": {
"name": "RA-B6010-48GT4X",
"thermal_manager": false,
"status_led": {
"controllable": false,
"colors": ["green", "blinking_green", "amber", "blinking_amber"]
},
"components": [
{
"name": "CPU CPLD"
},
{
"name": "MAC1 CPLD"
}
],
"fans": [
{
"name": "Fantray1_1",
"speed": {
"controllable": true,
"minimum": 30,
"maximum": 99
},
"status_led": {
"available": false,
"colors": ["off", "red", "amber", "green"]
}
},
{
"name": "Fantray2_1",
"speed": {
"controllable": true,
"minimum": 30,
"maximum": 99
},
"status_led": {
"available": false,
"colors": ["off", "red", "amber", "green"]
}
}
],
"fan_drawers":[
{
"name": "Fantray1",
"num_fans" : 1,
"status_led": {
"controllable": false,
"colors": ["amber", "green", "off"]
},
"fans": [
{
"name": "FanTray1_1",
"speed": {
"controllable": true,
"minimum": 30,
"maximum": 99
},
"status_led": {
"available": false
}
}
]
},
{
"name": "Fantray2",
"num_fans" : 1,
"status_led": {
"controllable": false,
"colors": ["amber", "green", "off"]
},
"fans": [
{
"name": "FanTray2_1",
"speed": {
"controllable": true,
"minimum": 30,
"maximum": 99
},
"status_led": {
"available": false
}
}
]
}
],
"psus": [
{
"name": "PSU 1",
"voltage": true,
"current": true,
"power": true,
"max_power": false,
"voltage_high_threshold": true,
"voltage_low_threshold": true,
"temperature": true,
"fans_target_speed": false,
"status_led": {
"controllable": false
}
},
{
"name": "PSU 2",
"voltage": true,
"current": true,
"power": true,
"max_power": false,
"voltage_high_threshold": true,
"voltage_low_threshold": true,
"temperature": true,
"fans_target_speed": false,
"status_led": {
"controllable": false
}
}
],
"thermals": [
{
"name": "ASIC_TEMP",
"controllable": false,
"low-crit-threshold": true,
"high-crit-threshold": true,
"low-threshold": true,
"high-threshold": true,
"minimum-recorded": true,
"maximum-recorded": true
},
{
"name": "CPU_TEMP",
"controllable": false,
"low-crit-threshold": true,
"high-crit-threshold": true,
"low-threshold": true,
"high-threshold": true,
"minimum-recorded": true,
"maximum-recorded": true
},
{
"name": "INLET_TEMP",
"controllable": false,
"low-crit-threshold": true,
"high-crit-threshold": true,
"low-threshold": true,
"high-threshold": true,
"minimum-recorded": true,
"maximum-recorded": true
},
{
"name": "OUTLET_TEMP",
"controllable": false,
"low-crit-threshold": true,
"high-crit-threshold": true,
"low-threshold": true,
"high-threshold": true,
"minimum-recorded": true,
"maximum-recorded": true
},
{
"name": "TPS53688_TEMP",
"controllable": false,
"low-crit-threshold": true,
"high-crit-threshold": true,
"low-threshold": true,
"high-threshold": true,
"minimum-recorded": true,
"maximum-recorded": true
}
],
"modules": [],
"sfps": []
},
"interfaces": {}
}

View File

@ -1 +0,0 @@
centec-arm64

View File

@ -1,22 +0,0 @@
#!/usr/bin/python
# -*- coding: UTF-8 -*-
RAGILE_CARDID = 0x00004099
RAGILE_PRODUCTNAME = "RA-B6010-48GT4X"
RAGILE_PART_NUMBER = "RJ000001"
RAGILE_LABEL_REVISION = "R01"
RAGILE_ONIE_VERSION = "2018.02"
RAGILE_MAC_SIZE = 3
RAGILE_MANUF_NAME = "Ragile"
RAGILE_MANUF_COUNTRY = "CHN"
RAGILE_VENDOR_NAME = "Ragile"
RAGILE_DIAG_VERSION = "0.1.0.15"
RAGILE_SERVICE_TAG = "www.ragile.com"
CPUEEPROMS = {"name":"cpueeprom","bus":5,"loc":0x57,"E2PRODUCT":'2', "E2TYPE":'4'}
# rg_eeprom = "1-0056/eeprom"
E2_LOC = {"bus":1, "devno":0x56}
E2_PROTECT = {}
FAN_PROTECT = {"bus":1, "devno":0x0d, "addr":0x19, "open":0x00, "close":0xff}

View File

@ -1,21 +0,0 @@
#!/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
except ImportError, e:
raise ImportError (str(e) + "- required module not found")
class board(eeprom_tlvinfo.TlvInfoDecoder):
def __init__(self, name, path, cpld_root, ro):
self.eeprom_path = "/sys/bus/i2c/devices/1-0056/eeprom"
super(board, self).__init__(self.eeprom_path, 0, '', True)

View File

@ -1,455 +0,0 @@
# sfputil.py
#
# Platform-specific SFP transceiver interface for SONiC
#
try:
import time
import subprocess
import re
import os
import threading
from sonic_sfp.sfputilbase import SfpUtilBase
except ImportError as e:
raise ImportError("%s - required module not found" % str(e))
class SfpUtil(SfpUtilBase):
"""Platform-specific SfpUtil class"""
PORT_START = 49
PORT_END = 52
PORTS_IN_BLOCK = 53
EEPROM_OFFSET = 9
SFP_DEVICE_TYPE = "optoe2"
QSFP_DEVICE_TYPE = "optoe1"
I2C_MAX_ATTEMPT = 3
SFP_STATUS_INSERTED = '1'
SFP_STATUS_REMOVED = '0'
TXWRT_PROTECT = 0X4E
TXWRT_NO_PROTECT = 0X59
_port_to_eeprom_mapping = {}
port_to_i2cbus_mapping ={}
port_dict = {}
port_presence_info = {}
port_reset_info = {}
port_txdis_info = {}
port_txwrt_info = {}
port_led_info = {}
port_rxlos_info = {}
port_txfault_info = {}
port_drop_info = {}
@property
def port_start(self):
return self.PORT_START
@property
def port_end(self):
return self.PORT_END
@property
def sfp_ports(self):
return list(range(self.PORT_START, self.PORTS_IN_BLOCK))
@property
def qsfp_ports(self):
return []
@property
def port_to_eeprom_mapping(self):
return self._port_to_eeprom_mapping
def __init__(self):
for x in range(self.PORT_START, self.PORTS_IN_BLOCK):
self.port_to_i2cbus_mapping[x] = (x - self.PORT_START + self.EEPROM_OFFSET)
self.port_presence_info["/sys/bus/i2c/devices/3-0030/sfp_presence1"] = [49, 50, 51, 52]
self.port_txdis_info["/sys/bus/i2c/devices/3-0030/tx_disable"] = [49, 50, 51, 52]
self.port_txwrt_info["/sys/bus/i2c/devices/3-0030/tx_write_protect"] = [49, 50, 51, 52]
# bit 1: los
self.port_rxlos_info["/sys/bus/i2c/devices/3-0030/sfp_rx_loss1"] = [49, 50, 51, 52]
# bit 1: fault
self.port_txfault_info["/sys/bus/i2c/devices/3-0030/sfp_tx_fault1"] = [49, 50, 51, 52]
# bit 1: drop
self.port_drop_info["/sys/bus/i2c/devices/3-0030/sfp_drop_record1"] = [49, 50, 51, 52]
SfpUtilBase.__init__(self)
def _sfp_read_file_path(self, file_path, offset, num_bytes):
attempts = 0
while attempts < self.I2C_MAX_ATTEMPT:
try:
file_path.seek(offset)
read_buf = file_path.read(num_bytes)
except:
attempts += 1
time.sleep(0.05)
else:
return True, read_buf
return False, None
def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset):
"""Tries to read the eeprom file to determine if the
device/sfp is present or not. If sfp present, the read returns
valid bytes. If not, read returns error 'Connection timed out"""
if not os.path.exists(sysfs_sfp_i2c_client_eeprompath):
return False
else:
with open(sysfs_sfp_i2c_client_eeprompath, "rb", buffering=0) as sysfsfile:
rv, buf = self._sfp_read_file_path(sysfsfile, offset, 1)
return rv
def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype):
try:
sysfs_nd_path = "%s/new_device" % sysfs_sfp_i2c_adapter_path
# Write device address to new_device file
nd_file = open(sysfs_nd_path, "w")
nd_str = "%s %s" % (devtype, hex(devaddr))
nd_file.write(nd_str)
nd_file.close()
except Exception as err:
print(("Error writing to new device file: %s" % str(err)))
return 1
else:
return 0
def _get_port_eeprom_path(self, port_num, devid):
sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter"
if port_num in list(self.port_to_eeprom_mapping.keys()):
sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[port_num]
else:
sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter"
i2c_adapter_id = self._get_port_i2c_adapter_id(port_num)
if i2c_adapter_id is None:
print("Error getting i2c bus num")
return None
# Get i2c virtual bus path for the sfp
sysfs_sfp_i2c_adapter_path = "%s/i2c-%s" % (sysfs_i2c_adapter_base_path,
str(i2c_adapter_id))
# If i2c bus for port does not exist
if not os.path.exists(sysfs_sfp_i2c_adapter_path):
print(("Could not find i2c bus %s. Driver not loaded?" % sysfs_sfp_i2c_adapter_path))
return None
sysfs_sfp_i2c_client_path = "%s/%s-00%s" % (sysfs_sfp_i2c_adapter_path,
str(i2c_adapter_id),
hex(devid)[-2:])
# If sfp device is not present on bus, Add it
if not os.path.exists(sysfs_sfp_i2c_client_path):
if port_num in self.qsfp_ports:
ret = self._add_new_sfp_device(
sysfs_sfp_i2c_adapter_path, devid, self.QSFP_DEVICE_TYPE)
else:
ret = self._add_new_sfp_device(
sysfs_sfp_i2c_adapter_path, devid, self.SFP_DEVICE_TYPE)
if ret != 0:
print("Error adding sfp device")
return None
sysfs_sfp_i2c_client_eeprom_path = "%s/eeprom" % sysfs_sfp_i2c_client_path
return sysfs_sfp_i2c_client_eeprom_path
def _read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes):
eeprom_raw = []
for i in range(0, num_bytes):
eeprom_raw.append("0x00")
rv, raw = self._sfp_read_file_path(sysfsfile_eeprom, offset, num_bytes)
if rv == False:
return None
try:
if isinstance(raw, str):
for n in range(0, num_bytes):
eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2)
else:
for n in range(0, num_bytes):
eeprom_raw[n] = hex(raw[n])[2:].zfill(2)
except Exception as err:
return None
return eeprom_raw
def get_eeprom_dom_raw(self, port_num):
if port_num in self.qsfp_ports:
# QSFP DOM EEPROM is also at addr 0x50 and thus also stored in eeprom_ifraw
return None
else:
# Read dom eeprom at addr 0x51
return self._read_eeprom_devid(port_num, self.IDENTITY_EEPROM_ADDR, 256)
def get_presence(self, port_num):
# Check for invalid port_num
if port_num < self.port_start or port_num > self.port_end:
return False
presence_path = None
for presence_key in self.port_presence_info:
if port_num in self.port_presence_info[presence_key]:
presence_path = presence_key
presence_offset = self.port_presence_info[presence_key].index(port_num)
break
if presence_path == None:
return False
try:
data = open(presence_path, "rb")
except IOError:
return False
presence_data = data.read(2)
if presence_data == "":
return False
result = int(presence_data, 16)
data.close()
# ModPrsL is active low
if result & (1 << presence_offset) == 0:
return True
return False
def get_low_power_mode(self, port_num):
return False
def set_low_power_mode(self, port_num, lpmode):
return False
def reset(self, port_num):
return False
def reset_all(self):
return False
def _do_write_file(self, file_handle, offset, value):
file_handle.seek(offset)
file_handle.write(hex(value))
def get_transceiver_change_event(self, timeout=0):
start_time = time.time()
currernt_port_dict = {}
forever = False
if timeout == 0:
forever = True
elif timeout > 0:
timeout = timeout / float(1000) # Convert to secs
else:
print(("get_transceiver_change_event:Invalid timeout value", timeout))
return False, {}
end_time = start_time + timeout
if start_time > end_time:
print(('get_transceiver_change_event:' \
'time wrap / invalid timeout value', timeout))
return False, {} # Time wrap or possibly incorrect timeout
while timeout >= 0:
# Check for OIR events and return updated port_dict
for x in range(self.PORT_START, self.PORTS_IN_BLOCK):
if self.get_presence(x):
currernt_port_dict[x] = self.SFP_STATUS_INSERTED
else:
currernt_port_dict[x] = self.SFP_STATUS_REMOVED
if (currernt_port_dict == self.port_dict):
if forever:
time.sleep(1)
else:
timeout = end_time - time.time()
if timeout >= 1:
time.sleep(1) # We poll at 1 second granularity
else:
if timeout > 0:
time.sleep(timeout)
return True, {}
else:
# Update reg value
self.port_dict = currernt_port_dict
return True, self.port_dict
print ("get_transceiver_change_event: Should not reach here.")
return False, {}
def tx_disable(self, port_num, disable):
if not self.get_presence(port_num):
return False
if port_num in self.sfp_ports:
txwrt_path = None
txdis_path = None
txdis_offset = 0
for key in self.port_txwrt_info:
if port_num in self.port_txwrt_info[key]:
txwrt_path = key
break
if txwrt_path == None:
return False
for key in self.port_txdis_info:
if port_num in self.port_txdis_info[key]:
txdis_path = key
txdis_offset = self.port_txdis_info[key].index(port_num)
break
if txdis_path == None:
return False
try:
with open(txwrt_path, "r+") as sys_file:
sres = hex(self.TXWRT_NO_PROTECT)[2:]
sys_file.write(sres)
with open(txdis_path, "r+") as sys_file:
txdis_data = sys_file.read(2)
if not txdis_data:
return False
result = int(txdis_data, 16)
if disable:
result = result | (1 << txdis_offset)
else:
result = result & (~(1 << txdis_offset))
sys_file.seek(0)
sres = hex(result)[2:]
print(result,sres)
sys_file.write(sres)
with open(txwrt_path, "r+") as sys_file:
sres = hex(self.TXWRT_PROTECT)[2:]
sys_file.write(sres)
except Exception as err:
print(err)
return False
return True
else:
return False
########### sysdiag ###########
def _get_cpld_info(self, port_num, info):
path = None
offset = 0
for key in info:
if port_num in info[key]:
path = key
offset = info[key].index(port_num)
break
return path, offset
def get_tx_disable(self, port_num):
# cur only support sfp moudle
if port_num not in self.sfp_ports:
return False
if not self.get_presence(port_num):
return False
path, offset = self._get_cpld_info(port_num, self.port_txdis_info)
if path == None:
return False
result = 0
try:
with open(path, "r") as sys_file:
data = sys_file.read(2)
result = int(data, 16)
except Exception as e:
print((str(e)))
return False
# 1: disable
if result & (1 << offset):
return True
else:
return False
def get_rx_los(self, port_num):
# cur only support sfp moudle
if port_num not in self.sfp_ports:
return False
path, offset = self._get_cpld_info(port_num, self.port_rxlos_info)
if path == None:
return False
result = 0
try:
with open(path, "r") as sys_file:
data = sys_file.read(2)
result = int(data, 16)
except Exception as e:
print((str(e)))
return False
# 1: los
if result & (1 << offset):
return True
else:
return False
def get_tx_fault(self, port_num):
# cur only support sfp moudle
if port_num not in self.sfp_ports:
return False
if not self.get_presence(port_num):
return False
path, offset = self._get_cpld_info(port_num, self.port_txfault_info)
if path == None:
return False
result = 0
try:
with open(path, "r") as sys_file:
data = sys_file.read(2)
result = int(data, 16)
except Exception as e:
print((str(e)))
return False
# 1: fault
if result & (1 << offset):
return True
else:
return False
return False
def get_plug_record(self, port_num):
if not self.get_presence(port_num):
return False
path, offset = self._get_cpld_info(port_num, self.port_drop_info)
if path == None:
return False
result = 0
try:
with open(path, "r") as sys_file:
data = sys_file.read(2)
result = int(data, 16)
except Exception as e:
print((str(e)))
return False
# 1: drop
if result & (1 << offset):
return True
else:
return False

View File

@ -1,112 +0,0 @@
#
# ssd_util.py
#
# Generic implementation of the SSD health API
# SSD models supported:
# - InnoDisk
# - StorFly
# - Virtium
try:
import subprocess
from sonic_platform_base.sonic_ssd.ssd_base import SsdBase
except ImportError as e:
raise ImportError (str(e) + "- required module not found")
HEALTH_CMD = "cat /sys/kernel/debug/mmc0/mmc0:0001/ext_csd | cut -c 537-538"
SERIAL_CMD = "cat /sys/bus/mmc/devices/mmc0\\:0001/serial"
FIRMWARE_CMD = "cat /sys/kernel/debug/mmc0/mmc0:0001/ext_csd | cut -c 509-522"
NOT_AVAILABLE = "N/A"
class SsdUtil(SsdBase):
"""
Generic implementation of the SSD health API
"""
def __init__(self, diskdev):
self.model = "KLMCG4JETD-B041"
self.temperature = NOT_AVAILABLE
self.vendor_ssd_info = "====No vendor information===="
self.health_list = [100,90,80,70,60,50,40,30,20,10,0]
try:
life_time = self._execute_shell(HEALTH_CMD)
if int(life_time) in range(1,12):
self.health = self.health_list[int(life_time) - 1]
else:
self.health = NOT_AVAILABLE
except Exception as e:
self.health = NOT_AVAILABLE
try:
self.firmware = self._execute_shell(FIRMWARE_CMD)
except Exception as e:
self.firmware = NOT_AVAILABLE
try:
serial = self._execute_shell(SERIAL_CMD)
self.serial = serial.replace("0x",'')
except Exception as e:
self.serial = NOT_AVAILABLE
def _execute_shell(self, cmd):
status, output = subprocess.getstatusoutput(cmd)
if status:
return None
return output
def get_health(self):
"""
Retrieves current disk health in percentages
Returns:
A float number of current ssd health
e.g. 83.5
"""
return self.health
def get_temperature(self):
"""
Retrieves current disk temperature in Celsius
Returns:
A float number of current temperature in Celsius
e.g. 40.1
"""
return self.temperature
def get_model(self):
"""
Retrieves model for the given disk device
Returns:
A string holding disk model as provided by the manufacturer
"""
return self.model
def get_firmware(self):
"""
Retrieves firmware version for the given disk device
Returns:
A string holding disk firmware version as provided by the manufacturer
"""
return self.firmware
def get_serial(self):
"""
Retrieves serial number for the given disk device
Returns:
A string holding disk serial number as provided by the manufacturer
"""
return self.serial
def get_vendor_output(self):
"""
Retrieves vendor specific data for the given disk device
Returns:
A string holding some vendor specific disk information
"""
return self.vendor_ssd_info

View File

@ -1,7 +0,0 @@
{
"skip_ledd": true,
"skip_xcvrd": false,
"skip_syseepromd": false,
"skip_thermalctld": false,
"skip_psud": false
}

View File

@ -11,9 +11,8 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_E530_24X2C_PLATFORM_MODULE)
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_E530_48S4X_PLATFORM_MODULE)
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_E530_24X2Q_PLATFORM_MODULE)
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(FS_S5800_48T4S_PLATFORM_MODULE)
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(RA_B6010_48GT4X_PLATFORM_MODULE)
ifeq ($(INSTALL_DEBUG_TOOLS),y)
ifeq ($(INSTALL_DEBUG_TOOLS),y)
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES)
$(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES))
else

View File

@ -1,9 +0,0 @@
MPATH := $($(RA_B6010_48GT4X_PLATFORM_MODULE)_SRC_PATH)
DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/centec-arm64/platform-modules-ragile.mk platform/centec-arm64/platform-modules-ragile.dep
DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
DEP_FILES += $(addprefix $(MPATH)/,$(shell cd $(MPATH) && git ls-files))
$(RA_B6010_48GT4X_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA
$(RA_B6010_48GT4X_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
$(RA_B6010_48GT4X_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES)

View File

@ -1,10 +0,0 @@
## RA-B6010-48GT4X
RA_B6010_48GT4X_PLATFORM_MODULE_VERSION =1.3
export RA_B6010_48GT4X_PLATFORM_MODULE_VERSION
RA_B6010_48GT4X_PLATFORM_MODULE = platform-modules-ra-b6010-48gt4x_$(RA_B6010_48GT4X_PLATFORM_MODULE_VERSION)_arm64.deb
$(RA_B6010_48GT4X_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-ragile
$(RA_B6010_48GT4X_PLATFORM_MODULE)_PLATFORM = arm64-ragile_ra-b6010-48gt4x-r0
$(RA_B6010_48GT4X_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON)
SONIC_DPKG_DEBS += $(RA_B6010_48GT4X_PLATFORM_MODULE)

View File

@ -7,7 +7,6 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk
include $(PLATFORM_PATH)/tsingma-bsp.mk
include $(PLATFORM_PATH)/platform-modules-centec-e530.mk
include $(PLATFORM_PATH)/platform-modules-fs.mk
include $(PLATFORM_PATH)/platform-modules-ragile.mk
SONIC_ALL += $(SONIC_ONE_IMAGE) \
$(DOCKER_FPM)

View File

@ -1,15 +0,0 @@
Copyright (C) 2019 Centec, 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -1 +0,0 @@
platform drivers for Centec E530 for the SONiC project

View File

@ -1,47 +0,0 @@
PWD = $(shell pwd)
CC ?=gcc
INSTALL_MOD_DIR ?=extra
KVERSION ?= $(shell uname -r)
KERNEL_SRC ?= /lib/modules/$(KVERSION)
EXTRA_CFLAGS:= -I$(M)/include
EXTRA_CFLAGS+= -Wall
ifdef ENABLE_GCOV
ifeq ($(ENABLE_GCOV), y)
EXTRA_CFLAGS+= -fprofile-arcs -ftest-coverage -lgcov
endif
endif # ENABLE_GCOV
SUB_BUILD_DIR = $(PWD)/build
DIR_KERNEL_SRC = $(PWD)/modules
SCRIPT_DIR = $(PWD)/script
SERVICE_DIR = $(PWD)/service
BLACK_DRIVER_CONF_DIR = $(PWD)/modprobe_conf
app_dir = $(PWD)/app
app_build_dir = $(app_dir)/build
modules_build_dir = $(DIR_KERNEL_SRC)/build
INSTALL_MODULE_DIR = $(SUB_BUILD_DIR)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR)
INSTALL_SCRIPT_DIR = $(SUB_BUILD_DIR)/usr/local/bin
INSTALL_SERVICE_DIR = $(SUB_BUILD_DIR)/lib/systemd/system
INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python3.9/dist-packages
INSTALL_BLACK_DRIVER = $(SUB_BUILD_DIR)/etc/modprobe.d
CTC_48GT4X_PHY_DIR = $(SUB_BUILD_DIR)/usr/share/sonic/device/arm64-ragile_ra-b6010-48gt4x-r0/RA-B6010-48GT4X
all:
$(MAKE) -C $(app_dir)
$(MAKE) -C $(DIR_KERNEL_SRC)
@if [ ! -d ${INSTALL_MODULE_DIR} ]; then mkdir -p ${INSTALL_MODULE_DIR} ;fi
@if [ ! -d ${INSTALL_SCRIPT_DIR} ]; then mkdir -p ${INSTALL_SCRIPT_DIR} ;fi
@if [ ! -d ${INSTALL_SERVICE_DIR} ]; then mkdir -p ${INSTALL_SERVICE_DIR} ;fi
@if [ ! -d ${CTC_48GT4X_PHY_DIR} ]; then mkdir -p ${CTC_48GT4X_PHY_DIR}/phy_drv ;fi
@if [ ! -d ${INSTALL_LIB_DIR} ]; then mkdir -p ${INSTALL_LIB_DIR} ;fi
@if [ -d $(PWD)/lib/ ]; then cp -r $(PWD)/lib/* ${INSTALL_LIB_DIR} ;fi
cp -r $(app_dir)/*.so $(CTC_48GT4X_PHY_DIR)/phy_drv
cp -r $(app_build_dir)/module/*.ko $(INSTALL_MODULE_DIR)
cp -r $(modules_build_dir)/*.ko $(INSTALL_MODULE_DIR)
cp -r $(app_dir)/build/app/* $(INSTALL_SCRIPT_DIR)
if [ -d $(SCRIPT_DIR) ]; then cp -r $(SCRIPT_DIR)/* $(INSTALL_SCRIPT_DIR) ;fi
if [ -d $(SERVICE_DIR) ]; then cp -r $(SERVICE_DIR)/* $(INSTALL_SERVICE_DIR) ;fi
@if [ -d $(INSTALL_SCRIPT_DIR) ]; then chmod +x $(INSTALL_SCRIPT_DIR)/* ;fi
clean:
rm -rf $(SUB_BUILD_DIR)

View File

@ -1,26 +0,0 @@
pes_parent_dir:=$(shell pwd)/$(lastword $(MAKEFILE_LIST))
pes_parent_dir:=$(shell dirname $(pes_parent_dir))
SUBDIRS=$(shell ls -l | grep ^d | awk '{if($$9 != "build") print $$9}')
INC = -I./inc
COMMON_OUT_PUT := $(shell pwd)/build
common_out_put_dir := $(COMMON_OUT_PUT)/app
common_module_dir := $(COMMON_OUT_PUT)/module/
export common_out_put_dir common_module_dir
all : CHECK $(SUBDIRS)
CHECK :
@echo $(pes_parent_dir)
$(SUBDIRS):ECHO
# make all
#@echo $@
make -C $@
ECHO:
@echo $(SUBDIRS)
.PHONY : clean
clean :
-rm -rf $(COMMON_OUT_PUT)

View File

@ -1,20 +0,0 @@
top_srcdir:= $(shell pwd)
include $(top_srcdir)/Rules.mk
export top_srcdir
firmware-y:=
firmware-y += firmware_driver_ispvme
firmware-y += firmware_upgrade_ispvme
.PHONY: all
all: build
.PHONY: build
build: $(firmware-y)
$(foreach dir,$(firmware-y),$(eval $(call compile_dirs,$(dir))))
.PHONY: rpmpkg
rpmpkg:
ifeq ("$(CONFIG_CPLD_UPGRADE_ISPVME)", "y")
#$(RPMPKG) $(install_cpld_dir) firmware-cpld-ispvme.spec git
endif

View File

@ -1,45 +0,0 @@
CC ?= $(CROSS)gcc
AR ?= $(CROSS)ar
AS ?= $(CROSS)as
LD ?= $(CROSS)ld
STRIP ?= $(CROSS)strip
install_root:=${top_srcdir}/images
install_header_dir:=${install_root}/header
install_adir:=$(install_root)/lib
install_symbol_dir:=$(install_root)/symbol
# symbol_files
symbol_files:=$(shell find $(EXPORT_SYMBOL) -name 'Module.symvers')
#
# symbol_files += $(shell find $(install_symbol_dir) -name 'Module.symvers')
# top root: install_rootfs_dir
# install_rootfs_dir
install_rootfs_dir:=$(install_root)/rootfs
# install_sodir
install_sodir:=$(install_rootfs_dir)/$(INSTALL_SODIR)
install_usr_bin_dir:=$(install_rootfs_dir)/usr/bin
# install_sbin_dir
install_sbin_dir:=$(install_rootfs_dir)/sbin
install_etc_dir:=$(install_rootfs_dir)/etc
export INSTALL_MOD_PATH:=$(ROOT)
BUILD_CFLAGS:=$(CFLAGS) -I$(install_header_dir)
BUILD_LDFLAGS:=$(LDFLAGS) -L/$(install_sodir) -L/$(install_adir)
define compile_dirs
.PHONY: $(1)
$(1):
@echo;echo "building $(1)..."
@$(MAKE) -C ${1}
endef
compile.c = $(CC) $(BUILD_CFLAGS) -d -c -o $@ $<
%.o: %.c
$(compile.c)

View File

@ -1,25 +0,0 @@
Summary: Firmware Upgrade Package
Name: firmware-cpld
Version: 1.0.0.%patch
Release: firmware
License: Ragile
Group: common
AutoReqProv: no
%clean
%description
[common]
%des_name
%des_ver
%des_target
%files
%attr(755,root,root)
/*

View File

@ -1,22 +0,0 @@
PWD = $(shell pwd)
EXTRA_CFLAGS:= -I$(M)/include
EXTRA_CFLAGS+= -Wall
ifdef ENABLE_GCOV
ifeq ($(ENABLE_GCOV), y)
EXTRA_CFLAGS+= -fprofile-arcs -ftest-coverage -lgcov
endif
endif # ENABLE_GCOV
RAGILE_PRODUCT = ra_b6010_48gt4x
firmware_driver-objs := firmware_ispvme.o
firmware_driver-objs += firmware_cpld_ispvme.o firmware_cpld_upgrade_ispvme.o
#ifndef CONFIG_FRM_PRODUCT_FILE
firmware_driver-objs += $(RAGILE_PRODUCT).o
$(warning $(firmware_driver-objs))
obj-m := firmware_driver.o
all:
$(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules
@if [ ! -d $(common_module_dir) ]; then mkdir -p $(common_module_dir) ;fi
cp -p $(PWD)/*.ko $(common_module_dir)

View File

@ -1,283 +0,0 @@
/**
* Copyright(C) 2013 Ragile Network. All rights reserved.
*/
/*
* firmware_cpld.c
* Original Author : support <support@ragile.com> 2013-10-25
*
* CPLD driver
*
* History
* v1.0 support <support@ragile.com> 2013-10-25 Initial version.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/of.h>
#include <asm/uaccess.h>
#include <firmware_ispvme.h>
#include <firmware_cpld_ispvme.h>
static int firmware_cpld_open(struct inode *inode, struct file *file)
{
firmware_cpld_t *cpld_info;
firmware_device_t *frm_dev;
dev_debug(firmware_debug(), "Open cpld device.\n");
frm_dev = firmware_get_device_by_minor(FIRMWARE_CPLD, MINOR(inode->i_rdev));
if (frm_dev == NULL) {
return -ENXIO;
}
file->private_data = frm_dev;
cpld_info = (firmware_cpld_t *)frm_dev->priv;
if (cpld_info != NULL && cpld_info->init_cpld) {
cpld_info->init_cpld();
}
if (cpld_info != NULL && cpld_info->init_chip) {
cpld_info->init_chip(0);
}
return FIRMWARE_SUCCESS;
}
static ssize_t firmware_cpld_read (struct file *file, char __user *buf, size_t count,
loff_t *offset)
{
return 0;
}
static ssize_t firmware_cpld_write (struct file *file, const char __user *buf, size_t count,
loff_t *offset)
{
return 0;
}
static loff_t firmware_cpld_llseek(struct file *file, loff_t offset, int origin)
{
return 0;
}
static long firmware_cpld_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
char value;
void __user *argp;
cmd_info_t cmd_info;
char *buf;
int ret;
argp = (void __user *)arg;
switch (cmd) {
case FIRMWARE_JTAG_TDI:
if (copy_from_user(&value, argp, sizeof(value))) {
return -EFAULT;
}
fwm_cpld_tdi_op(value);
break;
case FIRMWARE_JTAG_TCK:
if (copy_from_user(&value, argp, sizeof(value))) {
return -EFAULT;
}
fwm_cpld_tck_op(value);
break;
case FIRMWARE_JTAG_TMS:
if (copy_from_user(&value, argp, sizeof(value))) {
return -EFAULT;
}
fwm_cpld_tms_op(value);
break;
case FIRMWARE_JTAG_TDO:
value = fwm_cpld_tdo_op();
if (copy_to_user(argp, &value, sizeof(value))) {
return -EFAULT;
}
break;
case FIRMWARE_SET_GPIO_INFO:
/* set GPIO information */
if (copy_from_user(&cmd_info, argp, sizeof(cmd_info_t))) {
return -EFAULT;
}
buf = (char *) kzalloc(cmd_info.size + 1, GFP_KERNEL);
if (buf == NULL) {
return -ENOMEM;
}
if (copy_from_user(buf, cmd_info.data, cmd_info.size)) {
kfree(buf);
return -EFAULT;
}
ret = fmw_cpld_set_gpio_info((firmware_upg_gpio_info_t*)buf);
if (ret != FIRMWARE_SUCCESS) {
dev_debug(firmware_debug(), "Failed to set gpio info.\n");
kfree(buf);
return -ESRCH;
}
kfree(buf);
break;
case FIRMWARE_SET_DEBUG_ON:
/* DEBUG ON */
firmware_set_debug(1);
break;
case FIRMWARE_SET_DEBUG_OFF:
/* DEBUG_OFF */
firmware_set_debug(0);
break;
default:
return -ENOTTY;
}
return FIRMWARE_SUCCESS;
}
static int firmware_cpld_release(struct inode *inode, struct file *file)
{
firmware_cpld_t *cpld_info;
firmware_device_t *frm_dev;
frm_dev = (firmware_device_t *)(file->private_data);
cpld_info = (firmware_cpld_t *)(frm_dev->priv);
if (cpld_info != NULL && cpld_info->finish_chip) {
cpld_info->finish_chip(0);
}
if (cpld_info != NULL && cpld_info->finish_cpld) {
cpld_info->finish_cpld();
}
return 0;
}
static const struct file_operations cpld_dev_fops = {
.owner = THIS_MODULE,
.llseek = firmware_cpld_llseek,
.read = firmware_cpld_read,
.write = firmware_cpld_write,
.unlocked_ioctl = firmware_cpld_ioctl,
.open = firmware_cpld_open,
.release = firmware_cpld_release,
};
static int firmware_cpld_probe(struct platform_device *pdev)
{
const __be32 *slot;
int len;
int ret;
firmware_cpld_t *cpld_info;
firmware_device_t *frm_dev;
frm_dev = (firmware_device_t *) kzalloc(sizeof(firmware_device_t), GFP_KERNEL);
if (frm_dev == NULL) {
dev_debug(firmware_debug(), "Failed to kzalloc firmware device.\n");
return -EPERM;
}
slot = of_get_property(pdev->dev.of_node, "slot", &len);
if (slot && len == sizeof(*slot)) {
frm_dev->slot = be32_to_cpup(slot);
} else {
frm_dev->slot = firmware_get_device_num(FIRMWARE_CPLD) + 1;
}
snprintf(frm_dev->name, FIRMWARE_NAME_LEN - 1, "firmware_cpld_ispvme%d", frm_dev->slot - 1);
cpld_info = fmw_cpld_upg_get_cpld(frm_dev->name);
INIT_LIST_HEAD(&frm_dev->list);
frm_dev->type = FIRMWARE_CPLD;
frm_dev->dev.minor = MISC_DYNAMIC_MINOR;
frm_dev->dev.name = frm_dev->name;
frm_dev->dev.fops = &cpld_dev_fops;
frm_dev->priv = cpld_info;
dev_debug(firmware_debug(), "Register cpld firmware slot:%d, name:%s.\n", frm_dev->slot, frm_dev->name);
ret = firmware_device_register(frm_dev);
if (ret < 0) {
dev_debug(firmware_debug(), "Failed to register firmware device.\n");
kfree(frm_dev);
return -EPERM;
}
platform_set_drvdata(pdev, frm_dev);
return 0;
}
static int __exit firmware_cpld_remove(struct platform_device *dev)
{
firmware_device_t *frm_dev;
frm_dev = (firmware_device_t *)platform_get_drvdata(dev);
firmware_device_unregister(frm_dev);
kfree(frm_dev);
return 0;
}
static struct of_device_id cpld_match[] = {
{
.compatible = "firmware_cpld_ispvme",
},
{},
};
static struct platform_driver cpld_driver = {
.driver = {
.name = "firmware_cpld_ispvme",
.owner = THIS_MODULE,
.of_match_table = cpld_match,
},
.probe = firmware_cpld_probe,
.remove = firmware_cpld_remove,
};
static firmware_driver_t fmw_drv = {
.name = "firmware_cpld_ispvme",
.type = FIRMWARE_CPLD,
.drv = &cpld_driver,
};
void firmware_cpld_init(void)
{
int ret;
#if 0
struct device_node* node;
node = of_find_node_by_name(NULL, "cpld_upgrade");
if (node == NULL) {
pr_notice("No cpld_upgrade\r\n");
return;
}
pr_notice("Found cpld_upgrade\r\n");
#else
printk(KERN_INFO "Do init cpld_upgrade\r\n");
#endif
INIT_LIST_HEAD(&fmw_drv.list);
ret = fmw_cpld_upg_init();
if (ret < 0) {
return;
}
firmware_driver_register(&fmw_drv);
}
void firmware_cpld_exit(void)
{
fmw_cpld_upg_exit();
firmware_driver_unregister(&fmw_drv);
INIT_LIST_HEAD(&fmw_drv.list);
}

View File

@ -1,329 +0,0 @@
/**
* Copyright(C) 2013 Ragile Network. All rights reserved.
*/
/*
* firmware_cpld_upgrade.c
* Original Author : support <support@ragile.com>2013-10-25
*
* CPLD upgrade driver
*
* History
* v1.0 support <support@ragile.com> 2013-10-25 Initial version.
*
*/
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/ctype.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <firmware_ispvme.h>
#include <firmware_cpld_ispvme.h>
#include <config_ispvme.h>
/* TCK clock MAX 16MHz */
#define TCK_DELAY (current_fmw_cpld->tck_delay)
#if 0
static firmware_cpld_t default_fmw_cpld;
#endif
static firmware_cpld_t fmw_cpld[FIRMWARE_MAX_CPLD_NUM];
static firmware_cpld_t *current_fmw_cpld;
static firmware_set_gpio_info_func_t g_set_gpio_info_func = NULL;
void set_currrent_cpld_info(firmware_cpld_t *info)
{
current_fmw_cpld = info;
}
static void TDI_PULL_DOWN(void)
{
if (current_fmw_cpld != NULL && current_fmw_cpld->pull_tdi_down) {
current_fmw_cpld->pull_tdi_down();
} else {
dev_debug(firmware_debug(), "NO support TDI_PULL_DOWN.\n");
}
}
static void TDI_PULL_UP(void)
{
if (current_fmw_cpld != NULL && current_fmw_cpld->pull_tdi_up) {
current_fmw_cpld->pull_tdi_up();
} else {
dev_debug(firmware_debug(), "NO support TDI_PULL_UP.\n");
}
}
static void TCK_PULL_DOWN(void)
{
if (current_fmw_cpld != NULL && current_fmw_cpld->pull_tck_down) {
current_fmw_cpld->pull_tck_down();
} else {
dev_debug(firmware_debug(), "NO support TCK_PULL_DOWN.\n");
}
}
static void TCK_PULL_UP(void)
{
if (current_fmw_cpld != NULL && current_fmw_cpld->pull_tck_up) {
current_fmw_cpld->pull_tck_up();
} else {
dev_debug(firmware_debug(), "NO support TCK_PULL_UP.\n");
}
}
static void TMS_PULL_DOWN(void)
{
if (current_fmw_cpld != NULL && current_fmw_cpld->pull_tms_down) {
current_fmw_cpld->pull_tms_down();
} else {
dev_debug(firmware_debug(), "NO support TMS_PULL_DOWN.\n");
}
}
static void TMS_PULL_UP(void)
{
if (current_fmw_cpld != NULL && current_fmw_cpld->pull_tms_up) {
current_fmw_cpld->pull_tms_up();
} else {
dev_debug(firmware_debug(), "NO support TMS_PULL_UP.\n");
}
}
static int TDO_READ(void)
{
if (current_fmw_cpld != NULL && current_fmw_cpld->read_tdo) {
return current_fmw_cpld->read_tdo();
} else {
dev_debug(firmware_debug(), "NO support TDO_READ.\n");
return -1;
}
}
firmware_cpld_t *fmw_cpld_upg_get_cpld(char *name)
{
int i;
for (i = 0; i < FIRMWARE_MAX_CPLD_NUM; i++) {
if (fmw_cpld[i].is_used == 1 && strcmp(name, fmw_cpld[i].devname) == 0) {
return &fmw_cpld[i];
}
}
return NULL;
}
int fmw_cpld_upg_copy_firmware_info(firmware_cpld_t *info)
{
int i;
for (i = 0; i < FIRMWARE_MAX_CPLD_NUM; i++) {
if (fmw_cpld[i].is_used == 1) {
continue;
} else {
strncpy(fmw_cpld[i].devname, info->devname, FIRMWARE_DEV_NAME_LEN);
fmw_cpld[i].slot = info->slot;
fmw_cpld[i].chip_index = info->chip_index;
fmw_cpld[i].is_used = info->is_used;
fmw_cpld[i].tck_delay = info->tck_delay;
fmw_cpld[i].pull_tdi_up = info->pull_tdi_up;
fmw_cpld[i].pull_tdi_down = info->pull_tdi_down;
fmw_cpld[i].pull_tck_up = info->pull_tck_up;
fmw_cpld[i].pull_tck_down = info->pull_tck_down;
fmw_cpld[i].pull_tms_up = info->pull_tms_up;
fmw_cpld[i].pull_tms_down = info->pull_tms_down;
fmw_cpld[i].read_tdo = info->read_tdo;
fmw_cpld[i].init_cpld = info->init_cpld;
fmw_cpld[i].init_chip = info->init_chip;
fmw_cpld[i].finish_chip = info->finish_chip;
fmw_cpld[i].finish_cpld = info->finish_cpld;
fmw_cpld[i].touch_watch_dog = info->touch_watch_dog;
fmw_cpld[i].keeplive = info->keeplive;
fmw_cpld[i].get_version = info->get_version;
fmw_cpld[i].get_card_name = info->get_card_name;
return 0;
}
}
return -1;
}
int fmw_cpld_set_gpio_info(firmware_upg_gpio_info_t *info)
{
if (g_set_gpio_info_func == NULL) {
dev_debug(firmware_debug(), "g_set_gpio_info_func is null.\n");
return -1;
}
return g_set_gpio_info_func(info);
}
void fmw_cpld_reg_gpio_info_set_func(firmware_set_gpio_info_func_t func)
{
if (func == NULL) {
dev_debug(firmware_debug(), "fmw_cpld_register_gpio_info_set_func func = NULL.\n");
return;
}
g_set_gpio_info_func = func;
return;
}
#if 0
/* CPLD upgrade initialization operation */
static int fmw_cpld_upg_init_cpld(void)
{
gpio_request(JTAG_TDI, "cpld_upgrade");
gpio_request(JTAG_TCK, "cpld_upgrade");
gpio_request(JTAG_TMS, "cpld_upgrade");
gpio_request(JTAG_EN, "cpld_upgrade");
gpio_request(JTAG_TDO, "cpld_upgrade");
gpio_direction_output(JTAG_TDI, 1);
gpio_direction_output(JTAG_TCK, 1);
gpio_direction_output(JTAG_TMS, 1);
gpio_direction_output(JTAG_EN, 1);
gpio_direction_input(JTAG_TDO);
return 0;
}
/* CPLD upgrade completion operation */
static int fmw_cpld_upg_finish_cpld(void)
{
gpio_direction_output(JTAG_EN, 0);
gpio_free(JTAG_TDI);
gpio_free(JTAG_TCK);
gpio_free(JTAG_TMS);
gpio_free(JTAG_EN);
gpio_free(JTAG_TDO);
return 0;
}
/* TDI pull up */
static void fmw_cpld_upg_pull_tdi_up(void)
{
__gpio_set_value(JTAG_TDI, 1);
}
/* TDI pull down */
static void fmw_cpld_upg_pull_tdi_down(void)
{
__gpio_set_value(JTAG_TDI, 0);
}
/* TCK pull up */
static void fmw_cpld_upg_pull_tck_up(void)
{
__gpio_set_value(JTAG_TCK, 1);
}
/* TCK pull down */
static void fmw_cpld_upg_pull_tck_down(void)
{
__gpio_set_value(JTAG_TCK, 0);
}
/* TMS pull up */
static void fmw_cpld_upg_pull_tms_up(void)
{
__gpio_set_value(JTAG_TMS, 1);
}
/* TCK pull down */
static void fmw_cpld_upg_pull_tms_down(void)
{
__gpio_set_value(JTAG_TMS, 0);
}
/* read TDO */
static int fmw_cpld_upg_read_tdo(void)
{
return __gpio_get_value(JTAG_TDO);
}
#endif
#if 0
static firmware_cpld_t default_fmw_cpld = {
.devname = "default_firmware_cpld",
.slot = 1,
.is_used = 1,
.tck_delay = 50,
.pull_tdi_up = fmw_cpld_upg_pull_tdi_up,
.pull_tdi_down = fmw_cpld_upg_pull_tdi_down,
.pull_tck_up = fmw_cpld_upg_pull_tck_up,
.pull_tck_down = fmw_cpld_upg_pull_tck_down,
.pull_tms_up = fmw_cpld_upg_pull_tms_up,
.pull_tms_down = fmw_cpld_upg_pull_tms_down,
.read_tdo = fmw_cpld_upg_read_tdo,
.init_cpld = fmw_cpld_upg_init_cpld,
.finish_cpld = fmw_cpld_upg_finish_cpld,
};
#endif
/**
* Each product initializes its own related CPLD driver and needs to re-define the interface
* In the new interface, assign the relevant driver to fmw_cpld through the fmw_cpld_upg_copy_firmware_info interface
*/
int __attribute__ ((weak))fmw_cpld_product_init(void)
{
dev_debug(firmware_debug(), "Nothing cpld init for this product.\n");
return 0;
}
void __attribute__ ((weak))fmw_cpld_product_exit(void)
{
dev_debug(firmware_debug(), "Nothing exit init for this product.\n");
return;
}
int fmw_cpld_upg_init(void)
{
int ret;
mem_clear(fmw_cpld, FIRMWARE_MAX_CPLD_NUM * sizeof(firmware_cpld_t));
ret = fmw_cpld_product_init();
if (ret < 0) {
return ret;
}
#if 0
set_currrent_cpld_info(&default_fmw_cpld);
#endif
return 0;
}
void fmw_cpld_upg_exit(void)
{
fmw_cpld_product_exit();
return;
}
void fwm_cpld_tdi_op(int value)
{
if (value) {
TDI_PULL_UP();
} else {
TDI_PULL_DOWN();
}
}
void fwm_cpld_tck_op(int value)
{
if (value) {
TCK_PULL_UP();
} else {
TCK_PULL_DOWN();
}
}
void fwm_cpld_tms_op(int value)
{
if (value) {
TMS_PULL_UP();
} else {
TMS_PULL_DOWN();
}
}
int fwm_cpld_tdo_op()
{
return TDO_READ();
}

View File

@ -1,142 +0,0 @@
/**
* Copyright(C) 2013 Ragile Network. All rights reserved.
*/
/*
* firmware.c
* Original Author : support <support@ragile.com>2013-10-25
*
* firmware upgrade driver
*
* History
* v1.0 support <support@ragile.com> 2013-10-25 Initial version.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <firmware_ispvme.h>
#include <config_ispvme.h>
int drv_debug = 0;
module_param(drv_debug, int, S_IRUGO | S_IWUSR);
static LIST_HEAD(drv_list);
static LIST_HEAD(dev_list);
void firmware_set_debug(int value)
{
drv_debug = value;
return;
}
int firmware_debug(void)
{
return drv_debug;
}
int firmware_driver_register(firmware_driver_t *fw_drv)
{
int ret;
if (fw_drv == NULL) {
return FIRMWARE_FAILED;
}
ret = platform_driver_register(fw_drv->drv);
if (ret < 0) {
return FIRMWARE_FAILED;
}
list_add(&fw_drv->list, &drv_list);
return FIRMWARE_SUCCESS;
}
void firmware_driver_unregister(firmware_driver_t *fw_drv)
{
list_del_init(&fw_drv->list);
platform_driver_unregister(fw_drv->drv);
}
int firmware_get_device_num(int type)
{
int num;
firmware_device_t *tmp;
num = 0;
list_for_each_entry(tmp, &dev_list, list) {
if (tmp->type == type) {
num++;
}
}
return num;
}
firmware_device_t *firmware_get_device_by_minor(int type, int minor)
{
firmware_device_t *tmp;
list_for_each_entry(tmp, &dev_list, list) {
if (tmp->type == type && tmp->dev.minor == minor) {
return tmp;
}
}
return NULL;
}
int firmware_device_register(firmware_device_t *fw_dev)
{
int ret;
firmware_device_t *tmp;
if (fw_dev == NULL) {
return FIRMWARE_FAILED;
}
list_for_each_entry(tmp, &dev_list, list) {
if (strcmp(tmp->name, fw_dev->name) == 0) {
return FIRMWARE_FAILED;
}
}
ret = misc_register(&fw_dev->dev);
if (ret < 0) {
return FIRMWARE_FAILED;
}
list_add(&fw_dev->list, &dev_list);
return FIRMWARE_SUCCESS;
}
void firmware_device_unregister(firmware_device_t *fw_dev)
{
list_del(&fw_dev->list);
misc_deregister(&fw_dev->dev);
}
static int __init firmware_driver_init(void)
{
INIT_LIST_HEAD(&drv_list);
INIT_LIST_HEAD(&dev_list);
dev_debug(firmware_debug(), "firmware_driver_init cpld init.\n");
firmware_cpld_init();
return FIRMWARE_SUCCESS;
}
static void __exit firmware_driver_exit(void)
{
dev_debug(firmware_debug(), "firmware_driver_exit cpld exit.\n");
firmware_cpld_exit();
INIT_LIST_HEAD(&drv_list);
INIT_LIST_HEAD(&dev_list);
return;
}
module_init(firmware_driver_init);
module_exit(firmware_driver_exit);
MODULE_AUTHOR("support <support@ragile.com>");
MODULE_DESCRIPTION("ragile Platform Support");
MODULE_LICENSE("GPL");

View File

@ -1,10 +0,0 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__
#define JTAG_TDI (32)
#define JTAG_TDO (67)
#define JTAG_TCK (65)
#define JTAG_TMS (6)
#define JTAG_EN (50)
#endif /* __CONFIG_H__ */

View File

@ -1,52 +0,0 @@
#ifndef __FIRMWARE_CPLD_H__
#define __FIRMWARE_CPLD_H__
#define FIRMWARE_DEV_NAME_LEN 32
#define FIRMWARE_MAX_CPLD_NUM 16
typedef struct firmware_cpld_s {
char devname[FIRMWARE_DEV_NAME_LEN];
int slot;
int chip_index;
int is_used; /* 0:unused 1:used */
u32 tck_delay; /* delay time */
void (*pull_tdi_up)(void); /* TDI pull up */
void (*pull_tdi_down)(void); /* TDI pull dowm */
void (*pull_tck_up)(void); /* TCK pull up */
void (*pull_tck_down)(void); /* TCK pull dowm */
void (*pull_tms_up)(void); /* TMS pull up */
void (*pull_tms_down)(void); /* TCK pull dowm */
int (*read_tdo)(void); /* read ?TDO */
int (*init_cpld)(void); /* CPLD upgrade initialization operation */
int (*init_chip)(int slot); /* Chip related initialization operations */
int (*finish_chip)(int slot); /* Chip related completion operations */
int (*finish_cpld)(void); /* CPLD upgrade completion operation */
int (*check_upgrade_data)(char *src, int src_len, int *dst, int dst_len);
int (*touch_watch_dog)(void); /* touch watch dog related operation */
int (*keeplive)(void); /* KEEPLIVE */
int (*get_version)(int slot, char *ver, int len);
int (*get_card_name)(char *name, int len); /* get card name */
} firmware_cpld_t;
typedef int (*firmware_set_gpio_info_func_t)(firmware_upg_gpio_info_t *info);
extern int fmw_cpld_upg_get_chip_name(int slot, firmware_cpld_t *cpld, char *info, int len);
extern int fmw_cpld_upg_get_card_name(int slot, firmware_cpld_t *cpld, char *info, int len);
extern int fmw_cpld_upg_program(int slot, firmware_cpld_t *cpld, char *info, int len);
extern int fmw_cpld_upg_get_version(int slot, firmware_cpld_t *cpld, char *info, int len);
extern firmware_cpld_t *fmw_cpld_upg_get_cpld(char *name);
extern int fmw_cpld_upg_init(void);
extern void fmw_cpld_upg_exit(void);
extern int fmw_cpld_upg_copy_firmware_info(firmware_cpld_t *info);
extern int fmw_cpld_upg_get_chip_info(int slot, firmware_cpld_t *cpld, void *info, int len);
extern void fwm_cpld_tdi_op(int value);
extern void fwm_cpld_tck_op(int value);
extern void fwm_cpld_tms_op(int value);
extern int fwm_cpld_tdo_op(void);
extern void firmware_cpld_upgrade_init(void);
extern void firmware_cpld_upgrade_finish(void);
extern int fmw_cpld_set_gpio_info(firmware_upg_gpio_info_t *info);
extern void fmw_cpld_reg_gpio_info_set_func(firmware_set_gpio_info_func_t func);
#endif /* __FIRMWARE_CPLD_H__ */

View File

@ -1,90 +0,0 @@
#ifndef __FIRMWARE_H__
#define __FIRMWARE_H__
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <asm/ioctl.h>
#include <linux/string.h>
#define mem_clear(data, size) memset((data), 0, (size))
#define dev_debug(debug, fmt, arg...) \
if (debug == 1) { do{printk(KERN_ERR fmt,##arg);} while(0); }
#define FIRMWARE_NAME_LEN 48
#define FIRMWARE_FAILED (-1)
#define FIRMWARE_SUCCESS 0
enum firmware_type_s {
FIRMWARE_CPLD = 0,
FIRMWARE_FPGA,
};
/* ioctl command */
#define FIRMWARE_TYPE 'F'
#define FIRMWARE_JTAG_TDI _IOR(FIRMWARE_TYPE, 0, char)
#define FIRMWARE_JTAG_TDO _IOR(FIRMWARE_TYPE, 1, char)
#define FIRMWARE_JTAG_TCK _IOR(FIRMWARE_TYPE, 2, char)
#define FIRMWARE_JTAG_TMS _IOR(FIRMWARE_TYPE, 3, char)
#define FIRMWARE_JTAG_EN _IOR(FIRMWARE_TYPE, 4, char)
#define FIRMWARE_SET_DEBUG_ON _IOW(FIRMWARE_TYPE, 5, int) /* debug on */
#define FIRMWARE_SET_DEBUG_OFF _IOW(FIRMWARE_TYPE, 6, int) /* debug off */
#define FIRMWARE_SET_GPIO_INFO _IOR(FIRMWARE_TYPE, 7, int) /* Set GPIO pin configuration */
typedef struct cmd_info_s {
int size;
void __user *data;
} cmd_info_t;
typedef struct firmware_device_s {
struct list_head list; /* device linked list */
int type; /* the type of device */
int slot; /* position */
char name[FIRMWARE_NAME_LEN]; /* name */
struct miscdevice dev; /* device */
void *priv; /* private data */
} firmware_device_t;
typedef struct firmware_driver_s {
struct list_head list; /* linked list */
int type; /* type */
char name[FIRMWARE_NAME_LEN]; /* name */
struct platform_driver *drv; /* driver */
void *priv; /* private data */
} firmware_driver_t;
typedef struct gpio_group_s {
int pin;
int val;
int dir;
} gpio_group_t;
typedef struct firmware_upg_gpio_info_s {
int tdi;
int tck;
int tms;
int tdo;
int jtag_en;
int select;
gpio_group_t jtag_5;
gpio_group_t jtag_4;
gpio_group_t jtag_3;
gpio_group_t jtag_2;
gpio_group_t jtag_1;
} firmware_upg_gpio_info_t;
extern int firmware_debug(void);
extern void firmware_set_debug(int value);
extern firmware_device_t *firmware_get_device_by_minor(int type, int minor);
extern int firmware_get_device_num(int type);
extern int firmware_device_register(firmware_device_t *fw_dev);
extern void firmware_device_unregister(firmware_device_t *fw_dev);
extern int firmware_driver_register(firmware_driver_t *fw_drv);
extern void firmware_driver_unregister(firmware_driver_t *fw_drv);
extern void firmware_fpga_init(void);
extern void firmware_cpld_init(void);
extern void firmware_fpga_exit(void);
extern void firmware_cpld_exit(void);
#endif /* end of __FIRMWARE_H__ */

View File

@ -1,493 +0,0 @@
/**
* Copyright(C) 2013 Ragile Network. All rights reserved.
*/
/*
* ca-octeon-cmx.c
* Original Author : support <support@ragile.com>2013-10-25
* ca-octeon-cmx CPLD upgrade driver
*
* firmware upgrade driver
*
* History
* v1.0 support <support@ragile.com> 2013-10-25 Initial version.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio.h>
#if 0
#include <rg_switch_dev.h>
#include <ssa/kernel_module/ssa_dfd_intf.h>
#endif
#include <firmware_ispvme.h>
#include <firmware_cpld_ispvme.h>
#include "ra_b6010_48gt4x.h"
/* extern void cmic_gpio_set_output_value(int gpio, int val); */
firmware_device_info_t *current_info = NULL;
static firmware_device_info_t set_gpio_info;
static int set_gpio_info_flag = 0;
firmware_device_info_t default_cpld_info = {
.type = 0,
.tdi = JTAG_TDI,
.tck = JTAG_TCK,
.tms = JTAG_TMS,
.tdo = JTAG_TDO,
.jtag_en = JTAG_EN,
.select = -1,
.cmic_start_gpio = -1,
.cmic_end_gpio = -1,
};
firmware_device_info_t as13_cpld_info = {
.type = 0,
.tdi = 67,
.tck = JTAG_TCK,
.tms = JTAG_TMS,
.tdo = 32,
.jtag_en = JTAG_EN,
.select = 48,
.cmic_start_gpio = -1,
.cmic_end_gpio = -1,
};
static int firmware_cpld_gpio_is_from_cmic(int gpio)
{
if (current_info == NULL) {
return -1;
}
dev_debug(firmware_debug(), "gpio %d current_info.cmic_start_gpio %d current_info.cmic_end_gpio %d.\n",
gpio, current_info->cmic_start_gpio, current_info->cmic_end_gpio);
if ((current_info->cmic_start_gpio == -1) || (current_info->cmic_end_gpio == -1)) {
return 0;
}
if ((gpio >= current_info->cmic_start_gpio) && (gpio <= current_info->cmic_end_gpio)) {
return 1;
}
return 0;
}
static int firmware_cpld_gpio_get_value(int gpio)
{
#if 0
int ret;
ret = firmware_cpld_gpio_is_from_cmic(gpio);
if (ret < 0) {
dev_debug(firmware_debug(), "firmware_cpld_gpio_is_from_cmic gpio %d failed ret %d.\n",
gpio, ret);
return -1;
}
if (ret == 1) {
/* Not currently supported */
dev_debug(firmware_debug(), "gpio %d not support to get value.\n", gpio);
return -1;
} else {
return __gpio_get_value(gpio);
}
#endif
return __gpio_get_value(gpio);
}
static void firmware_cpld_gpio_set_output_value(int gpio, int val)
{
#if 0
int ret;
ret = firmware_cpld_gpio_is_from_cmic(gpio);
if (ret < 0) {
dev_debug(firmware_debug(), "firmware_cpld_gpio_is_from_cmic gpio %d failed ret %d.\n",
gpio, ret);
return;
}
if (ret == 1) {
__gpio_set_value(gpio, val);
/*cmic_gpio_set_output_value(gpio, val);*/
} else {
__gpio_set_value(gpio, val);
}
#endif
__gpio_set_value(gpio, val);
}
static void firmware_cpld_gpio_set_direction(int gpio, int out)
{
if (out) {
gpio_direction_output(gpio, 1);
} else {
gpio_direction_input(gpio);
}
return;
}
static void firmware_cpld_gpio_request(int gpio, char *name)
{
int ret;
ret = firmware_cpld_gpio_is_from_cmic(gpio);
if (ret < 0) {
dev_debug(firmware_debug(), "firmware_cpld_gpio_is_from_cmic gpio %d failed ret %d.\n",
gpio, ret);
return;
}
if (ret == 1) {
/* do nothing */
} else {
gpio_request(gpio, name);
}
return;
}
static void firmware_cpld_gpio_free(int gpio)
{
int ret;
ret = firmware_cpld_gpio_is_from_cmic(gpio);
if (ret < 0) {
dev_debug(firmware_debug(), "firmware_cpld_gpio_is_from_cmic gpio %d failed ret %d.\n",
gpio, ret);
return;
}
if (ret == 1) {
/* do nothing */
} else {
gpio_free(gpio);
}
return;
}
/* CPLD upgrade initialization operation */
static int init_cpld(void)
{
if (current_info == NULL) {
return -1;
}
firmware_cpld_gpio_request(current_info->tdi, "cpld_upgrade");
firmware_cpld_gpio_request(current_info->tck, "cpld_upgrade");
firmware_cpld_gpio_request(current_info->tms, "cpld_upgrade");
firmware_cpld_gpio_request(current_info->jtag_en, "cpld_upgrade");
if (current_info->select >= 0) {
firmware_cpld_gpio_request(current_info->select, "cpld_upgrade");
}
firmware_cpld_gpio_request(current_info->tdo, "cpld_upgrade");
if (current_info->jtag_4.pin >= 0){
firmware_cpld_gpio_request(current_info->jtag_1.pin, "cpld_upgrade");
firmware_cpld_gpio_request(current_info->jtag_2.pin, "cpld_upgrade");
firmware_cpld_gpio_request(current_info->jtag_3.pin, "cpld_upgrade");
firmware_cpld_gpio_request(current_info->jtag_4.pin, "cpld_upgrade");
firmware_cpld_gpio_request(current_info->jtag_5.pin, "cpld_upgrade");
}
return 0;
}
/* CPLD upgrade completion operation */
static int finish_cpld(void)
{
if (current_info == NULL) {
return -1;
}
firmware_cpld_gpio_set_output_value(current_info->jtag_en, 0);
if (current_info->select >= 0) {
firmware_cpld_gpio_set_output_value(current_info->select, 0);
}
if (current_info->jtag_4.pin >= 0) {
gpio_direction_input(current_info->jtag_4.pin);
gpio_direction_input(current_info->jtag_1.pin);
gpio_direction_input(current_info->jtag_2.pin);
gpio_direction_input(current_info->jtag_3.pin);
gpio_direction_input(current_info->jtag_5.pin);
}
firmware_cpld_gpio_free(current_info->tdi);
firmware_cpld_gpio_free(current_info->tck);
firmware_cpld_gpio_free(current_info->tms);
firmware_cpld_gpio_free(current_info->jtag_en);
firmware_cpld_gpio_free(current_info->tdo);
if (current_info->jtag_4.pin >= 0) {
firmware_cpld_gpio_free(current_info->jtag_1.pin);
firmware_cpld_gpio_free(current_info->jtag_2.pin);
firmware_cpld_gpio_free(current_info->jtag_3.pin);
firmware_cpld_gpio_free(current_info->jtag_4.pin);
firmware_cpld_gpio_free(current_info->jtag_5.pin);
}
if (current_info->select >= 0) {
firmware_cpld_gpio_free(current_info->select);
}
if (set_gpio_info_flag == 1) {
memcpy(current_info, &set_gpio_info, sizeof(firmware_device_info_t));
set_gpio_info_flag = 0;
}
dev_debug(firmware_debug(), "%s %d\n", __func__, __LINE__);
return 0;
}
static void init_chip_pre(void)
{
dev_debug(firmware_debug(), "%s %d\n", __func__, __LINE__);
/* to be reset every time when upgrade,solve the use of MAC side GPIO,
During the startup process, the MAC terminal will be reset, causing the problem of invalid settings */
firmware_cpld_gpio_set_direction(current_info->tdi, 1);
firmware_cpld_gpio_set_direction(current_info->tck, 1);
firmware_cpld_gpio_set_direction(current_info->tms, 1);
firmware_cpld_gpio_set_direction(current_info->jtag_en, 1);
if (current_info->select >= 0) {
firmware_cpld_gpio_set_direction(current_info->select, 1);
}
if (current_info->jtag_4.pin >= 0) {
firmware_cpld_gpio_set_direction(current_info->jtag_4.pin, 1);
firmware_cpld_gpio_set_direction(current_info->jtag_3.pin, 1);
firmware_cpld_gpio_set_direction(current_info->jtag_2.pin, 1);
firmware_cpld_gpio_set_direction(current_info->jtag_1.pin, 1);
firmware_cpld_gpio_set_direction(current_info->jtag_5.pin, 1);
}
firmware_cpld_gpio_set_output_value(current_info->tdi, 1);
firmware_cpld_gpio_set_output_value(current_info->tck, 1);
firmware_cpld_gpio_set_output_value(current_info->tms, 1);
firmware_cpld_gpio_set_output_value(current_info->jtag_en, 1);
if (current_info->jtag_4.pin >= 0) {
firmware_cpld_gpio_set_output_value(current_info->jtag_1.pin, current_info->jtag_1.val);
firmware_cpld_gpio_set_output_value(current_info->jtag_2.pin, current_info->jtag_2.val);
firmware_cpld_gpio_set_output_value(current_info->jtag_3.pin, current_info->jtag_3.val);
firmware_cpld_gpio_set_output_value(current_info->jtag_4.pin, current_info->jtag_4.val);
firmware_cpld_gpio_set_output_value(current_info->jtag_5.pin, current_info->jtag_5.val);
}
if (current_info->select >= 0) {
firmware_cpld_gpio_set_output_value(current_info->select, 1);
}
firmware_cpld_gpio_set_direction(current_info->tdo, 0);
return;
}
static int init_chip(int slot)
{
dev_debug(firmware_debug(), "%s %d\n", __func__, __LINE__);
if (current_info == NULL) {
return -1;
}
init_chip_pre();
dev_debug(firmware_debug(), "tdi %d %d\n",current_info->tdi, firmware_cpld_gpio_get_value(current_info->tdi));
dev_debug(firmware_debug(), "tdo %d %d\n",current_info->tdo, firmware_cpld_gpio_get_value(current_info->tdo));
dev_debug(firmware_debug(), "tck %d %d\n",current_info->tck, firmware_cpld_gpio_get_value(current_info->tck));
dev_debug(firmware_debug(), "tms %d %d\n",current_info->tms, firmware_cpld_gpio_get_value(current_info->tms));
dev_debug(firmware_debug(), " jtag_en:%d %d\n",current_info->jtag_en, firmware_cpld_gpio_get_value(current_info->jtag_en));
if (current_info->select >= 0) {
dev_debug(firmware_debug(), " select:%d %d\n",current_info->select, firmware_cpld_gpio_get_value(current_info->select));
}
return 0;
}
static int finish_chip(int slot)
{
if (current_info == NULL) {
return -1;
}
firmware_cpld_gpio_set_output_value(current_info->jtag_en, 0);
if (current_info->select >= 0) {
firmware_cpld_gpio_set_output_value(current_info->select, 0);
}
if (current_info->jtag_4.pin >= 0) {
firmware_cpld_gpio_set_output_value(current_info->jtag_4.pin, 1);
}
return 0;
}
/* TDI pull up */
static void pull_tdi_up(void)
{
if (current_info == NULL) {
return;
}
firmware_cpld_gpio_set_output_value(current_info->tdi, 1);
}
/* TDI pull dowm */
static void pull_tdi_down(void)
{
if (current_info == NULL) {
return;
}
firmware_cpld_gpio_set_output_value(current_info->tdi, 0);
}
/* TCK pull up */
static void pull_tck_up(void)
{
if (current_info == NULL) {
return;
}
firmware_cpld_gpio_set_output_value(current_info->tck, 1);
}
/* TCK pull down */
static void pull_tck_down(void)
{
if (current_info == NULL) {
return;
}
firmware_cpld_gpio_set_output_value(current_info->tck, 0);
}
/* TMS pull up */
static void pull_tms_up(void)
{
if (current_info == NULL) {
return;
}
firmware_cpld_gpio_set_output_value(current_info->tms, 1);
}
/* TCK pull dowm */
static void pull_tms_down(void)
{
if (current_info == NULL) {
return;
}
firmware_cpld_gpio_set_output_value(current_info->tms, 0);
}
/* read TDO */
static int read_tdo(void)
{
if (current_info == NULL) {
return -1;
}
return firmware_cpld_gpio_get_value(current_info->tdo);
}
int B6510_fmw_set_gpio_info(firmware_upg_gpio_info_t *info)
{
if (info == NULL) {
dev_debug(firmware_debug(), "set gpio info info %p is null.\n", info);
return -1;
}
set_gpio_info.tdi = info->tdi;
set_gpio_info.tck = info->tck;
set_gpio_info.tms = info->tms;
set_gpio_info.tdo = info->tdo;
set_gpio_info.jtag_en = info->jtag_en;
set_gpio_info.select= info->select;
set_gpio_info.jtag_5.pin = info->jtag_5.pin;
set_gpio_info.jtag_4.pin = info->jtag_4.pin;
set_gpio_info.jtag_3.pin = info->jtag_3.pin;
set_gpio_info.jtag_2.pin = info->jtag_2.pin;
set_gpio_info.jtag_1.pin = info->jtag_1.pin;
set_gpio_info.jtag_5.val = info->jtag_5.val;
set_gpio_info.jtag_4.val = info->jtag_4.val;
set_gpio_info.jtag_3.val = info->jtag_3.val;
set_gpio_info.jtag_2.val = info->jtag_2.val;
set_gpio_info.jtag_1.val = info->jtag_1.val;
set_gpio_info_flag = 1;
dev_debug(firmware_debug(), "set gpio info[tdi:%d tck:%d tms:%d tdo:%d jtag_en:%d select:%d].\n",
info->tdi, info->tck, info->tms, info->tdo, info->jtag_en, info->select);
return 0;
}
firmware_cpld_t fmw_cpld0 = {
.devname = "firmware_cpld_ispvme0",
.slot = 1,
.chip_index = 1,
.is_used = 1,
.tck_delay = 60,
.pull_tdi_up = pull_tdi_up,
.pull_tdi_down = pull_tdi_down,
.pull_tck_up = pull_tck_up,
.pull_tck_down = pull_tck_down,
.pull_tms_up = pull_tms_up,
.pull_tms_down = pull_tms_down,
.read_tdo = read_tdo,
.init_cpld = init_cpld,
.init_chip = init_chip,
.finish_chip = finish_chip,
.finish_cpld = finish_cpld,
.get_version = NULL,
};
static void cpld_release(struct device *dev)
{
return;
}
static struct platform_device cpld = {
.name = "firmware_cpld_ispvme",
.id = 0,
.num_resources = 0,
.dev = {
.release = cpld_release,
}
};
extern void set_currrent_cpld_info(firmware_cpld_t *info);
extern int dfd_get_my_card_type(void);
int fmw_cpld_product_init(void)
{
current_info = NULL;
#if 0
int dev_type;
int i;
dev_type = drv_get_my_dev_type();
if (dev_type < 0) {
printk(KERN_ERR "Failed to get device type, when upgrade cpld.\n");
return FIRMWARE_FAILED;
}
for (i = 0; i < sizeof(cpld_info)/sizeof(cpld_info[0]); i++) {
if (cpld_info[i].type == dev_type) {
current_info = &cpld_info[i];
printk(KERN_ERR "device type 0x%x match i %d.\n", dev_type, i);
printk(KERN_ERR "tdi[%d] tck[%d] tms[%d] tdo[%d] jtat_en[%d].\n", current_info->tdi,
current_info->tck, current_info->tms, current_info->tdo, current_info->jtag_en);
}
}
#endif
if (current_info == NULL) {
current_info = &default_cpld_info;
}
platform_device_register(&cpld);
fmw_cpld_upg_copy_firmware_info(&fmw_cpld0);
/* fmw_cpld0.init_cpld(); */
set_currrent_cpld_info(&fmw_cpld0);
fmw_cpld_reg_gpio_info_set_func(B6510_fmw_set_gpio_info);
return FIRMWARE_SUCCESS;
}
void fmw_cpld_product_exit(void)
{
platform_device_unregister(&cpld);
return;
}

View File

@ -1,29 +0,0 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__
#include <firmware_cpld_ispvme.h>
#define JTAG_TDI (32)
#define JTAG_TDO (67)
#define JTAG_TCK (65)
#define JTAG_TMS (6)
#define JTAG_EN (50)
typedef struct firmware_device_info_s {
int type;
int tdi;
int tck;
int tms;
int tdo;
int jtag_en;
int select;
gpio_group_t jtag_5;
gpio_group_t jtag_4;
gpio_group_t jtag_3;
gpio_group_t jtag_2;
gpio_group_t jtag_1;
int cmic_start_gpio;
int cmic_end_gpio;
} firmware_device_info_t;
#endif /* __CONFIG_H__ */

View File

@ -1,39 +0,0 @@
include $(top_srcdir)/Rules.mk
OBJ = firmware_app_ispvme.o debug_ispvme.o hardware.o ispvm_ui.o ivm_core.o dfd_fpga_pkt.o dfd_fpga_upg.o dfd_fpga_debug.o
LIB += $(BUILD_CFALGS) $(BUILD_LDFLAGS) -lpthread -lreadline -lncurses
ifdef ENABLE_GCOV
ifeq ($(ENABLE_GCOV), y)
LIB += -lgcov
endif
endif # ENABLE_GCOV
APP = firmware_upgrade
BUILD_DIR = tmp
ELF_FILE = $(BUILD_DIR)/$(APP)
MAP_FILE = $(BUILD_DIR)/$(APP).map.sym
INCLUDE = -Iinclude
.PHONY: build
build:make-dir $(addprefix $(BUILD_DIR)/,$(OBJ))
$(CC) -o $(ELF_FILE) $(addprefix $(BUILD_DIR)/,$(OBJ)) $(LINKFLAGS) $(LIB)
$(NM) $(ELF_FILE) | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' \
| sort > $(MAP_FILE)
@if [ ! -d $(common_out_put_dir) ]; then mkdir -p $(common_out_put_dir) ;fi
cp -p $(ELF_FILE) $(common_out_put_dir)
# build
.PHONY: make-dir
make-dir:
@mkdir -p $(BUILD_DIR)
$(BUILD_DIR)/%.o:%.c
$(CC) -c $(CFLAGS) $(INCLUDE) $< -o $@
.PHONY: install
install:
echo "firmware_upgrade install success."
cp -p $(ELF_FILE) $(common_out_put_dir)
.PHONY: clean
clean:
rm -rf $(BUILD_DIR)

View File

@ -1,28 +0,0 @@
#ifndef __COMMON_H__
#define __COMMON_H__
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#define FIRMWARE_TYPE 'F'
#define FIRMWARE_JTAG_TDI _IOR(FIRMWARE_TYPE, 0, char)
#define FIRMWARE_JTAG_TDO _IOR(FIRMWARE_TYPE, 1, char)
#define FIRMWARE_JTAG_TCK _IOR(FIRMWARE_TYPE, 2, char)
#define FIRMWARE_JTAG_TMS _IOR(FIRMWARE_TYPE, 3, char)
#define FIRMWARE_JTAG_EN _IOR(FIRMWARE_TYPE, 4, char)
#define FIRMWARE_SET_DEBUG_ON _IOW(FIRMWARE_TYPE, 5, int) /* debug on */
#define FIRMWARE_SET_DEBUG_OFF _IOW(FIRMWARE_TYPE, 6, int) /* debug off */
#define FIRMWARE_SET_GPIO_INFO _IOR(FIRMWARE_TYPE, 7, int) /* set GPIO pin configuration */
#define JTAG_TDI (1)
#define JTAG_TDO (2)
#define JTAG_TCK (3)
#define JTAG_TMS (4)
#define JTAG_ENABLE (5)
#define JTAG_TRST (6)
#endif

View File

@ -1,67 +0,0 @@
/**
* Copyright(C) 2013 Ragile Network. All rights reserved.
*/
/*
* debug.c
*
* firmware upgrade debug control
*
* Original Author : support <support@ragile.com>2013-10-25
*/
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <dirent.h>
#include <ctype.h>
#include <debug_ispvme.h>
/**
* firmware_upgrade_debug:handle debug switch
*
* analyse file /tmp/firmware_upgrade_debug,return the information correspoding to debug
*
* return:return DEBUG_OFF when debug off,return DEBUG_ON when debug on,return DEBUG_IGNORE in other cases
*/
int firmware_upgrade_debug(void)
{
int size;
FILE *fp;
char debug_info[DEBUG_INFO_LEN] = {0};
fp = fopen(DEBUG_FILE, "r");
if (fp == NULL) {
return DEBUG_IGNORE;
}
size = fread(debug_info, DEBUG_INFO_LEN - 1, 1, fp);
if (size < 0) {
fclose(fp);
return DEBUG_IGNORE;
}
if (strncmp(debug_info, DEBUG_ON_INFO, 1) == 0) {
fclose(fp);
return DEBUG_APP_ON;
}
if (strncmp(debug_info, DEBUG_ON_KERN, 1) == 0) {
fclose(fp);
return DEBUG_KERN_ON;
}
if (strncmp(debug_info, DEBUG_ON_ALL, 1) == 0) {
fclose(fp);
return DEBUG_ALL_ON;
}
if (strncmp(debug_info, DEBUG_OFF_INFO, 1) == 0) {
fclose(fp);
return DEBUG_OFF;
}
fclose(fp);
return DEBUG_IGNORE;
}

View File

@ -1,120 +0,0 @@
/*
* Copyright(C) 2001-2013 Ragile Network. All rights reserved.
*/
/*
* dfd_debug.c
*
* Function:Device framework driver debugging interface
*
* History
* v1.0 support <support@ragile.com> 2013-10-25 Initial version.
*/
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include "dfd_fpga_debug.h"
#undef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) /sizeof((a)[0]))
/* Debug switch storage of dfd module */
int g_dfd_fpga_debug = 0x0;
/**
* dfd_fpga_pkt_debug_set - Debug switch setting interface of dfd module
* @type: Types of debugging information
* @enable: enable/Disable debugging information
*
* return 0 if success, otherwise reuturn -1.
*/
static int dfd_fpga_pkt_debug_set(int type, int enable)
{
if (type >= DFD_DBG_CNT || type < 0) {
DFD_ERROR("unknow dfd debug type=%d\n", type);
return -1;
}
if (enable) {
g_dfd_fpga_debug |= 1U << type;
} else {
g_dfd_fpga_debug &= ~(1U << type);
}
return 0;
}
void dfd_fpga_open_debug(int val)
{
if (val == 1) {
(void)dfd_fpga_pkt_debug_set(DFD_DBG_ERR, 1);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_WARN, 1);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_VBOSE, 1);
} else if (val == 2) {
(void)dfd_fpga_pkt_debug_set(DFD_FLOCK_DBG_VBOSE, 1);
} else if (val == 3) {
(void)dfd_fpga_pkt_debug_set(DFD_DBG_ERR, 1);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_WARN, 1);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_VBOSE, 1);
(void)dfd_fpga_pkt_debug_set(DFD_FLOCK_DBG_VBOSE, 1);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_DBG, 1);
} else if (val == 4) {
(void)dfd_fpga_pkt_debug_set(DFD_DBG_DBG, 1);
} else {
(void)dfd_fpga_pkt_debug_set(DFD_DBG_ERR, 0);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_WARN, 0);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_VBOSE, 0);
(void)dfd_fpga_pkt_debug_set(DFD_FLOCK_DBG_VBOSE, 0);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_DBG, 0);
}
return;
}
void dfd_fpga_debug_init(void)
{
FILE *fp;
char buf[10] = {0};
fp = fopen(DFD_DEBUG_FILE, "r");
if (fp != NULL) {
if (fgets(buf, sizeof(buf), fp) != NULL) {
if (strstr(buf, DFD_DEBUG_SET_NO_WARN) != NULL) {
(void)dfd_fpga_pkt_debug_set(DFD_DBG_ERR, 1);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_WARN, 0);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_VBOSE, 0);
(void)dfd_fpga_pkt_debug_set(DFD_FLOCK_DBG_VBOSE, 0);
} else if (strstr(buf, DFD_DEBUG_SET_NO_VBOSE) != NULL) {
(void)dfd_fpga_pkt_debug_set(DFD_DBG_ERR, 1);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_WARN, 1);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_VBOSE, 0);
(void)dfd_fpga_pkt_debug_set(DFD_FLOCK_DBG_VBOSE, 0);
} else if (strstr(buf, DFD_DEBUG_SET_NO_FLOCK_VBOSE) != NULL) {
(void)dfd_fpga_pkt_debug_set(DFD_DBG_ERR, 1);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_WARN, 1);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_VBOSE, 1);
(void)dfd_fpga_pkt_debug_set(DFD_FLOCK_DBG_VBOSE, 0);
} else if (strstr(buf, DFD_DEBUG_SET_ALL) != NULL) {
(void)dfd_fpga_pkt_debug_set(DFD_DBG_ERR, 1);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_WARN, 1);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_VBOSE, 1);
(void)dfd_fpga_pkt_debug_set(DFD_FLOCK_DBG_VBOSE, 1);
(void)dfd_fpga_pkt_debug_set(DFD_DBG_DBG, 1);
} else if (strstr(buf, DFD_DEBUG_SET_DBG) != NULL) {
(void)dfd_fpga_pkt_debug_set(DFD_DBG_DBG, 1);
} else if (strstr(buf, DFD_DEBUG_SET_FLOCK) != NULL) {
(void)dfd_fpga_pkt_debug_set(DFD_FLOCK_DBG_VBOSE, 1);
}
}
fclose(fp);
}
return;
}

View File

@ -1,70 +0,0 @@
#ifndef _DFD_FPGA_DEBUG_H_
#define _DFD_FPGA_DEBUG_H_
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define DFD_DEBUG_FILE "/sbin/.dfd_debug_flag"
#define DFD_DEBUG_SET_NO_WARN "0x1"
#define DFD_DEBUG_SET_NO_VBOSE "0x3"
#define DFD_DEBUG_SET_NO_FLOCK_VBOSE "0x7"
#define DFD_DEBUG_SET_ALL "0xf"
#define DFD_DEBUG_SET_DBG "0xd"
#define DFD_DEBUG_SET_FLOCK "0xe"
#define mem_clear(data, size) memset((data), 0, (size))
#define DFD_DEBUG_CHECK(type) (g_dfd_fpga_debug & (1U << (type)))
#define DFD_ERROR(fmt, args...) do { \
if (DFD_DEBUG_CHECK(DFD_DBG_ERR)) { \
printf("[%s-%s]:<File:%s, Func:%s, Line:%d>\n" fmt, "DFD", "err", \
__FILE__, __FUNCTION__, __LINE__, ##args); \
} \
} while (0)
#define DFD_WARN(fmt, args...) do { \
if (DFD_DEBUG_CHECK(DFD_DBG_WARN)) { \
printf("[%s-%s]:<File:%s, Func:%s, Line:%d>\n" fmt, "DFD", "warn", \
__FILE__, __FUNCTION__, __LINE__, ##args); \
} \
} while (0)
#define DFD_VERBOS(fmt, args...) do { \
if (DFD_DEBUG_CHECK(DFD_DBG_VBOSE)) { \
printf("[%s-%s]:<File:%s, Func:%s, Line:%d>\n" fmt, "DFD", "vbose", \
__FILE__, __FUNCTION__, __LINE__, ##args); \
} \
} while (0)
#define DFD_FLOCK_VERBOS(fmt, args...) do { \
if (DFD_DEBUG_CHECK(DFD_FLOCK_DBG_VBOSE)) { \
printf("[%s-%s]:<File:%s, Func:%s, Line:%d>\n" fmt, "DFD", "flock_vbose", \
__FILE__, __FUNCTION__, __LINE__, ##args); \
} \
} while (0)
#define DFD_DBG(fmt, args...) do { \
if (DFD_DEBUG_CHECK(DFD_DBG_DBG)) { \
printf("" fmt,\
##args); \
} \
} while (0)
/* define the type of debugging information */
typedef enum {
DFD_DBG_ERR,
DFD_DBG_WARN,
DFD_DBG_VBOSE,
DFD_FLOCK_DBG_VBOSE,
DFD_DBG_DBG,
DFD_DBG_CNT
} DFD_DEBUG_TYPE_E;
extern int g_dfd_fpga_debug;
int dfd_fpga_debug_set(int type, int enable);
void dfd_fpga_open_debug(int val);
void dfd_fpga_debug_init(void);
#endif

View File

@ -1,321 +0,0 @@
/*
* Copyright(C) 2001-2012 Ragile Network. All rights reserved.
*/
/*
* dfd_fpga_pkt.c
*
* FPGA message interaction related interface
*
* History
* v1.0 support <support@ragile.com> 2013-10-25 Initial version.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/prctl.h>
#include <pthread.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <sys/mman.h>
#include "dfd_fpga_pkt.h"
#include "dfd_fpga_debug.h"
#define DFD_FPGA_FAC_MODE_CONFIG_FILE "/tmp/.factory_disabale_cli_tty"
#if 1
#define DFD_FPGA_PKT_SEND_PKT_TO_FRAME
#endif
void dfd_fpga_pkt_print(uint8_t *buf, int buf_len)
{
int i;
for (i = 0; i < buf_len; i++) {
if ((i % 16) == 0) {
DFD_DBG("\n");
}
DFD_DBG("%02x ", buf[i]);
}
DFD_DBG("\n");
return;
}
static unsigned int littel_endian_byte_to_word32(uint8_t *byte_buf, int len)
{
uint8_t tmp_buf[4];
unsigned int word;
word = 0;
mem_clear(tmp_buf, 4);
memcpy(tmp_buf, byte_buf, len < 4 ? len : 4);
word = tmp_buf[0] | (tmp_buf[1] << 8) | (tmp_buf[2] << 16) | (tmp_buf[3] << 24);
return word;
}
static int littel_endian_word32_to_byte(uint8_t *byte_buf, int len, unsigned int word)
{
uint8_t tmp_buf[4];
int ret;
if (len < 4) {
DFD_ERROR("Not enough buf, word32 to byte: len[%d], word[0x%x]\n");
return -1;
}
mem_clear(tmp_buf, 4);
tmp_buf[0] = word & 0xff;
tmp_buf[1] = (word >> 8) & 0xff;
tmp_buf[2] = (word >> 16) & 0xff;
tmp_buf[3] = (word >> 24) & 0xff;
memcpy(byte_buf, tmp_buf, 4);
return 0;
}
static int open_pci_dev(dfd_pci_dev_priv_t *pci_priv, int is_cfg)
{
int file, ret;
char filename[DFD_PCI_MAX_NAME_SIZE];
if (is_cfg) {
ret = snprintf(filename, DFD_PCI_MAX_NAME_SIZE,
"/sys/class/pci_bus/%04x:%02x/device/%04x:%02x:%02x.%d/config",
0, pci_priv->pcibus, 0, pci_priv->pcibus, pci_priv->slot, pci_priv->fn);
} else {
ret = snprintf(filename, DFD_PCI_MAX_NAME_SIZE,
"/sys/class/pci_bus/%04x:%02x/device/%04x:%02x:%02x.%d/resource%d",
0, pci_priv->pcibus, 0, pci_priv->pcibus, pci_priv->slot, pci_priv->fn,
pci_priv->bar);
}
filename[ret] = '\0';
if ((file = open(filename, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) {
DFD_ERROR("Error: Could not open file %s\n", filename);
}
return file;
}
/**
* dfd_fpga_buf_read - provide FPGA write register interface (address must be four-byte aligned)
* @dst: The data structure of sslot and unit corresponding to the target chip
* @addr: address (four-byte alignment). For the byte alignment required by the specific FPGA address, please refer to the FPGA manual
* @buf: Buffer for reading data
* @wr_len: the length of reading data,please refer to the FPGA manual for the length of the specific FPGA address requirements
* return: return if success,else return -1
*/
int dfd_fpga_pci_read(dfd_pci_dev_priv_t *pci_priv, int offset, uint8_t *buf, int rd_len)
{
int ret, fd;
unsigned int data;
uint8_t *ptr, *ptr_data;
struct stat sb;
int i;
int len, align;
if ((pci_priv == NULL) || (buf == NULL)) {
DFD_ERROR("pci_prive or read buf is null.\n");
return -1;
}
if ((pci_priv->align < 1) || (offset & (pci_priv->align - 1)) || (rd_len & (pci_priv->align - 1))) {
DFD_ERROR("offset[%d] or rd_len[%d] don't align[%d].\n", offset, rd_len, pci_priv->align);
return -1;
}
if ((fd = open_pci_dev(pci_priv, 0)) < 0) {
return -1;
}
if ((ret = fstat(fd, &sb)) == -1) {
DFD_ERROR("Error: Could not fstat : %s\n", strerror(errno));
close(fd);
return -1;
}
if (offset + rd_len >= sb.st_size) {
DFD_ERROR("Error: offset is out of range\n");
close(fd);
return -1;
}
if ((ptr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0)) == MAP_FAILED) {
DFD_ERROR("Error: Could not mmap : %s or resource is IO\n", strerror(errno));
close(fd);
return -1;
}
align = pci_priv->align;
len = rd_len;
ret = 0;
i = 0;
ptr_data = ptr + offset;
while((i < len) && (ret == 0)){
if (align == 4) {
data = *((volatile unsigned int *)(ptr_data + i));
ret = littel_endian_word32_to_byte(buf + i, len - i, data);
i += 4;
} else {
ret = -1;
}
}
munmap(ptr, sb.st_size);
close(fd);
return ret;
}
/**
* dfd_fpga_buf_write -provide FPGA write register interface (address must be four-byte aligned)
* @dst: The data structure of sslot and unit corresponding to the target chip
* @addr: address (four-byte alignment). For the byte alignment required by the specific FPGA address, please refer to the FPGA manual
* @buf: Buffer for reading data
* @wr_len: the length of reading data,please refer to the FPGA manual for the length of the specific FPGA address requirements
* return: return if success,else return -1
*/
int dfd_fpga_pci_write(dfd_pci_dev_priv_t *pci_priv, int offset, uint8_t *buf, int wr_len)
{
int ret, fd;
unsigned int data;
uint8_t *ptr, *ptr_data;
struct stat sb;
int i;
int len, align;
if ((pci_priv == NULL) || (buf == NULL)) {
DFD_ERROR("pci_prive or write buf is null.\n");
return -1;
}
if ((pci_priv->align < 1) || (offset & (pci_priv->align - 1)) || (wr_len & (pci_priv->align - 1))) {
DFD_ERROR("offset[%d] or rd_len[%d] don't align[%d].\n", offset, wr_len, pci_priv->align);
return -1;
}
if ((fd = open_pci_dev(pci_priv, 0)) < 0) {
return -1;
}
if ((ret = fstat(fd, &sb)) == -1) {
DFD_ERROR("Error: Could not fstat : %s\n", strerror(errno));
close(fd);
return -1;
}
if (offset + wr_len >= sb.st_size) {
DFD_ERROR("Error: offset is out of range\n");
close(fd);
return -1;
}
if ((ptr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0)) == MAP_FAILED) {
DFD_ERROR("Error: Could not mmap : %s or resource is IO\n", strerror(errno));
close(fd);
return -1;
}
align = pci_priv->align;
len = wr_len;
ret = 0;
i = 0;
ptr_data = ptr + offset;
while((i < len) && (ret == 0)){
if (align == 4) {
data = littel_endian_byte_to_word32(buf + i,len - i);
*((volatile unsigned int *)(ptr_data + i)) = data;
i += 4;
} else {
ret = -1;
}
}
munmap(ptr, sb.st_size);
close(fd);
return ret;
}
/**
* dfd_fpga_read_word -provide FPGA read register interface (address must be four-byte aligned)
* @addr: address (four-byte alignment)
* @val: the returned number of reading
* return: return 0 if success,else return failure
*/
int dfd_fpga_read_word(dfd_pci_dev_priv_t *pci_priv, int addr, int *val)
{
int ret, i;
uint8_t tmp[DFD_FPGA_PKT_WORD_LEN];
if ((pci_priv == NULL) || (val == NULL) || (addr & 0x03)) {
DFD_ERROR("Input para invalid pci_priv %p val %p addr 0x%x.\n", pci_priv, val, addr);
return -1;
}
ret = dfd_fpga_pci_read(pci_priv, addr, tmp, DFD_FPGA_PKT_WORD_LEN);
if (ret) {
DFD_ERROR("dfd_fpga_pci_read addr 0x%x failed ret %d.\n", addr, ret);
return ret;
}
*val = littel_endian_byte_to_word32(tmp,DFD_FPGA_PKT_WORD_LEN);
for (i = 0; i < DFD_FPGA_PKT_WORD_LEN; i++) {
DFD_VERBOS("tmp[%d]: 0x%x.\n", i, tmp[i]);
}
DFD_VERBOS("dfd_fpga_read_word addr 0x%x val 0x%x.\n", addr, *val);
return 0;
}
/**
* dfd_fpga_write_word -provide FPGA write register interface (address must be four-byte aligned)
* @addr: address (four-byte alignment)
* @val: Data written
* return: return 0 if success,else return failure
*/
int dfd_fpga_write_word(dfd_pci_dev_priv_t *pci_priv, int addr, int val)
{
int ret, i;
uint8_t tmp[DFD_FPGA_PKT_WORD_LEN];
if ((pci_priv == NULL) || (addr & 0x03)) {
DFD_ERROR("Input para invalid pci_priv %p addr 0x%x.\n", pci_priv, addr);
return -1;
}
littel_endian_word32_to_byte(tmp, DFD_FPGA_PKT_WORD_LEN, val);
for (i = 0; i < DFD_FPGA_PKT_WORD_LEN; i++) {
DFD_VERBOS("tmp[%d]: 0x%x.\n", i, tmp[i]);
}
ret = dfd_fpga_pci_write(pci_priv, addr, tmp, DFD_FPGA_PKT_WORD_LEN);
if (ret) {
DFD_ERROR("dfd_fpga_pci_write addr 0x%x failed ret %d.\n", addr, ret);
return ret;
}
DFD_VERBOS("dfd_fpga_write_word addr 0x%x val 0x%x.\n", addr, val);
return 0;
}

View File

@ -1,95 +0,0 @@
#ifndef __DFD_FPGA_PKT_H__
#define __DFD_FPGA_PKT_H__
typedef enum dfd_fpga_pkt_op_type_e {
DFD_FPGA_PKT_OP_TYPE_READ = 0, /* read */
DFD_FPGA_PKT_OP_TYPE_WRITE = 1, /* write */
DFD_FPGA_PKT_OP_TYPE_END,
} dfd_fpga_pkt_op_type_t;
typedef enum dfd_fpga_pkt_ack_type_e {
DFD_FPGA_PKT_ACK_TYPE_NO_ERROR = 0, /* successful operation */
DFD_FPGA_PKT_ACK_TYPE_FCS_ERROR = 1, /* operation FCS check error */
DFD_FPGA_PKT_ACK_TYPE_FAIL_ERROR = 2, /* operation failed */
DFD_FPGA_PKT_ACK_TYPE_END,
} dfd_fpga_pkt_ack_type_t;
typedef enum dfd_rv_s {
DFD_RV_OK = 0,
DFD_RV_INIT_ERR = 1,
DFD_RV_SLOT_INVALID = 2,
DFD_RV_MODE_INVALID = 3,
DFD_RV_MODE_NOTSUPPORT = 4,
DFD_RV_TYPE_ERR = 5,
DFD_RV_DEV_NOTSUPPORT = 6,
DFD_RV_DEV_FAIL = 7,
DFD_RV_INDEX_INVALID = 8,
DFD_RV_NO_INTF = 9,
DFD_RV_NO_NODE = 10,
DFD_RV_NODE_FAIL = 11,
} dfd_rv_t;
typedef struct dfd_pci_dev_priv_s {
int pcibus;
int slot;
int fn;
int bar;
int offset;
int times;
int align;
int fpga_upg_base;
}dfd_pci_dev_priv_t;
#define DFD_PCI_MAX_NAME_SIZE 256
#define DFD_MAX_FPGA_NUM (8)
#define DFD_FPGA_PKT_WORD_LEN (4)
#define DFD_FPGA_PKT_MAC_LEN (6)
#define DFD_FPGA_PKT_PAYLOAD_WORD_DATA_LEN (4)
#define DFD_FPGA_PKT_WORD_RW_LEN (1)/* for each access, according to 1 WORD, 4 bytes to access FPGA */
#define DFD_FPGA_PKT_ETYPE (0xfff9)
#define DFD_FPGA_PKT_PAYLOAD_ADDR_LEN (4)
#define DFD_FPGA_PKT_PAYLOAD_LENGTH_LEN (2)
#define DFD_FPGA_PKT_PAYLOAD_ADDR_OFFSET (0)
#define DFD_FPGA_PKT_PAYLOAD_LENGTH_OFFSET (DFD_FPGA_PKT_PAYLOAD_ADDR_LEN)
#define DFD_FPGA_PKT_PAYLOAD_DATA_OFFSET ((DFD_FPGA_PKT_PAYLOAD_ADDR_LEN) + (DFD_FPGA_PKT_PAYLOAD_LENGTH_LEN))
#define DFD_FPGA_PKT_GET_DATA(payload) (((uint8_t*)(payload)) + DFD_FPGA_PKT_PAYLOAD_DATA_OFFSET)
#define DFD_FPGA_PKT_GET_PAYLOAD_LEN(len) ((DFD_FPGA_PKT_PAYLOAD_ADDR_LEN) + (DFD_FPGA_PKT_PAYLOAD_LENGTH_LEN) + (len))
#pragma pack (1)
typedef struct dfd_fpga_pkt_payload_s {
uint32_t addr; /* the address of reading and writting */
uint16_t length; /* the length of reading and writting */
uint32_t data; /* read and write data (for read operations, you don't need to care about this field) */
} dfd_fpga_pkt_payload_t;
typedef struct dfd_fpga_pkt_rd_payload_s {
uint32_t addr; /* the address of reading */
uint16_t length; /* the length of reading */
} dfd_fpga_pkt_rd_payload_t;
#pragma pack ()
typedef enum fpga_version_e {
FPGA_VER_00 = 0x00,
FPGA_VER_01,
FPGA_VER_02,
FPGA_VER_03,
FPGA_VER_04,
FPGA_VER_05,
FPGA_VER_06,
} fpga_version_t;
int dfd_fpga_upg_init(void);
int dfd_fpga_write_word(dfd_pci_dev_priv_t *pci_priv, int addr, int val);
int dfd_fpga_read_word(dfd_pci_dev_priv_t *pci_priv, int addr, int *val);
int dfd_fpga_pci_write(dfd_pci_dev_priv_t *pci_priv, int offset, uint8_t *buf, int wr_len);
int dfd_fpga_pci_read(dfd_pci_dev_priv_t *pci_priv, int offset, uint8_t *buf, int rd_len);
extern int drv_get_my_dev_type(void);
#endif

View File

@ -1,906 +0,0 @@
/**
* Copyright(C) 2013 Ragile Network. All rights reserved.
*/
/*
* firmware_app.c
* firmware upgrade
* v1.0 support <support@ragile.com> 2013-10-25 Initial version.
*/
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <dirent.h>
#if 0
#include <ssa/lib/ssa_dfd_intf.h>
#include <autoconf.h>
#endif
#include <firmware_app_ispvme.h>
static firmware_card_info_t g_card_info[] = {
{
.dev_type = RA_B6010_48GT4X,
.slot_num = 1,
.card_name = "RA_B6010_48GT4X",
.gpio_info = {
/* slot 0 */
{
.tdi = 507,
.tck = 505,
.tms = 506,
.tdo = 508,
.jtag_en = 504,
.select = -1,
.jtag_5 = GPIO(-1, 0,1)
.jtag_4 = GPIO(-1, 0,1)
.jtag_3 = GPIO(-1, 1,1)
.jtag_2 = GPIO(-1, 0,1)
.jtag_1 = GPIO(-1, 1,1)
},
},
},
{
.dev_type = RA_B6010_48GT4X_R,
.slot_num = 1,
.card_name = "RA_B6010_48GT4X_R",
.gpio_info = {
/* slot 0 */
{
.tdi = 507,
.tck = 505,
.tms = 506,
.tdo = 508,
.jtag_en = 504,
.select = -1,
.jtag_5 = GPIO(-1, 0,1)
.jtag_4 = GPIO(-1, 0,1)
.jtag_3 = GPIO(-1, 1,1)
.jtag_2 = GPIO(-1, 0,1)
.jtag_1 = GPIO(-1, 1,1)
},
},
},
};
static int is_debug_on;
static int dfd_my_type = 0;
#if 0
#if defined(CONFIG_FRM_PRODUCT_NAME)
#define CONFIG_RAGILE_PRODUCT_NAME CONFIG_FRM_PRODUCT_NAME
#else
#define CONFIG_RAGILE_PRODUCT_NAME "card"
#endif
#endif
#define DFD_TYPE_FILE "/sys/module/ragile_common/parameters/dfd_my_type"
#define DFD_TYPE_BUFF_SIZE (256)
static int is_vme_file(char *file_name)
{
char *tmp;
tmp = strchr(file_name, '.');
if (strcmp(tmp, ".bin") == 0) {
return 0;
} else if (strcmp(tmp, ".vme") == 0) {
return 1;
} else {
return -1;
}
}
int drv_get_my_dev_type(void)
{
int type;
int fd;
char rbuf[DFD_TYPE_BUFF_SIZE];
int read_len;
if (dfd_my_type != 0) {
dbg_print(is_debug_on, "my_type = 0x%x\r\n", dfd_my_type);
return dfd_my_type;
}
fd = open(DFD_TYPE_FILE, O_RDONLY);
if (fd < 0) {
dbg_print(is_debug_on, "can't open device %s.\r\n", DFD_TYPE_FILE);
return RA_B6010_48GT4X; /* Avoid B6510 to obtain different device types */
}
mem_clear(rbuf, DFD_TYPE_BUFF_SIZE);
type = 0;
read_len = read(fd, rbuf, DFD_TYPE_BUFF_SIZE - 1);
if (read_len > 0) {
type = strtoul(rbuf, NULL, 0);
}
close(fd);
dfd_my_type = type;
dbg_print(is_debug_on, "read dfd type file is %s read_len %d, dfd_my_type 0x%x\n", rbuf, read_len, dfd_my_type);
return dfd_my_type;
}
firmware_card_info_t* firmware_get_card_info(int dev_type)
{
int i;
int size;
size = (sizeof(g_card_info) /sizeof((g_card_info)[0]));
dbg_print(is_debug_on, "Enter dev_type 0x%x size %d.\n", dev_type, size);
for (i = 0; i < size; i++) {
if (g_card_info[i].dev_type == dev_type) {
dbg_print(is_debug_on, "match dev_type 0x%x.\n", dev_type);
return &g_card_info[i];
}
}
dbg_print(is_debug_on, "dismatch dev_type 0x%x.\n", dev_type);
return NULL;
}
int firmware_get_card_name(char *name, int len)
{
int dev_type;
firmware_card_info_t *info;
dbg_print(is_debug_on, "Enter len %d.\n", len);
dev_type = drv_get_my_dev_type();
if (dev_type < 0) {
dbg_print(is_debug_on, "drv_get_my_dev_type failed ret %d.\n", dev_type);
return FIRMWARE_FAILED;
}
info = firmware_get_card_info(dev_type);
if (info == NULL) {
dbg_print(is_debug_on, "firmware_get_card_info dev_type %d failed.\n", dev_type );
return FIRMWARE_FAILED;
}
strncpy(name, info->card_name, len - 1);
dbg_print(is_debug_on, "Leave dev_type 0x%x name %s, info->name %s.\n", dev_type,
name, info->card_name);
return FIRMWARE_SUCCESS;
}
int get_debug_value(void)
{
return is_debug_on;
}
#if 0
/* each device implements its own corresponding interface */
int __attribute__ ((weak)) firmware_get_card_name(char *name, int len)
{
strncpy(name, CONFIG_RAGILE_PRODUCT_NAME, len - 1);
return FIRMWARE_SUCCESS;
}
#endif
static int firmware_check_file_is_dir(char *dir, char *file_name)
{
int ret;
struct stat buf;
char tmp[FIRMWARE_FILE_DIR_LEN];
if (strcmp(file_name, ".") == 0 || strcmp(file_name, "..") == 0) {
return -1;
}
mem_clear(tmp, FIRMWARE_FILE_DIR_LEN);
snprintf(tmp, FIRMWARE_FILE_DIR_LEN - 1, "%s/%s", dir, file_name);
ret = stat(tmp, &buf);
if (ret < 0) {
return -1;
}
if (S_ISDIR(buf.st_mode)) {
return 1;
}
return 0;
}
static inline int firmware_error_type(int action, name_info_t *info)
{
if (info == NULL) {
return ERR_FW_UPGRADE;
}
if (info->type == FIRMWARE_CPLD) {
switch (action) {
case FIRMWARE_ACTION_CHECK:
return ERR_FW_CHECK_CPLD_UPGRADE;
case FIRMWARE_ACTION_UPGRADE:
return ERR_FW_DO_CPLD_UPGRADE;
default:
return ERR_FW_UPGRADE;
}
} else if (info->type == FIRMWARE_FPGA) {
switch (action) {
case FIRMWARE_ACTION_CHECK:
return ERR_FW_CHECK_FPGA_UPGRADE;
case FIRMWARE_ACTION_UPGRADE:
return ERR_FW_DO_FPGA_UPGRADE;
default:
return ERR_FW_UPGRADE;
}
} else {
return ERR_FW_UPGRADE;
}
}
/* analyze file's name,Name rule: card name_firmware type_slot number_firmware chip name.bin*/
static int firmware_parse_file_name(char *name, name_info_t *info)
{
int i;
char *tmp, *start;
char slot[FIRMWARE_NAME_LEN];
dbg_print(is_debug_on, "Parse file name: %s\n", name);
start = name;
/* card name */
tmp = strchr(start, '_');
if (tmp == NULL) {
dbg_print(is_debug_on, "Failed to get card name form file name: %s.\n", name);
return firmware_error_type(FIRMWARE_ACTION_CHECK, NULL);
}
strncpy(info->card_name, start,
(tmp - start > FIRMWARE_NAME_LEN - 1) ? (FIRMWARE_NAME_LEN - 1) : (tmp - start));
/* firmware type */
start = tmp + 1;
tmp = strchr(start, '_');
if (tmp == NULL) {
dbg_print(is_debug_on, "Failed to get upgrade type form file name: %s.\n", name);
return firmware_error_type(FIRMWARE_ACTION_CHECK, NULL);
}
if (strncmp(start, FIRMWARE_CPLD_NAME, tmp - start) == 0) {
info->type = FIRMWARE_CPLD;
} else if (strncmp(start, FIRMWARE_FPGA_NAME, tmp - start) == 0) {
info->type = FIRMWARE_FPGA;
} else {
info->type = FIRMWARE_OTHER;
}
/* slot number */
start = tmp + 1;
tmp = strchr(start, '_');
if (tmp == NULL) {
dbg_print(is_debug_on, "Failed to get slot form file name: %s.\n", name);
return firmware_error_type(FIRMWARE_ACTION_CHECK, info);
}
mem_clear(slot, FIRMWARE_NAME_LEN);
strncpy(slot, start,
((tmp - start > FIRMWARE_NAME_LEN - 1) ? FIRMWARE_NAME_LEN - 1 : tmp - start));
for (i = 0; i < FIRMWARE_NAME_LEN && slot[i] != '\0'; i++) {
if (!isdigit(slot[i])) {
return firmware_error_type(FIRMWARE_ACTION_CHECK, info);
}
}
dbg_print(is_debug_on, "get slot info: %s.\n", name);
info->slot = strtoul(slot, NULL, 10);
dbg_print(is_debug_on, "get slot info slot: %d.\n", info->slot);
/* firmware chip name */
start = tmp + 1;
tmp = strchr(start, '_');
if (tmp == NULL) {
dbg_print(is_debug_on, "Failed to get chip name form file name: %s.\n", name);
return firmware_error_type(FIRMWARE_ACTION_CHECK, info);
}
strncpy(info->chip_name, start,
(tmp - start > FIRMWARE_NAME_LEN - 1) ? (FIRMWARE_NAME_LEN - 1) : (tmp - start));
/* version */
start = tmp + 1;
tmp = strstr(start, ".vme");
if (tmp == NULL) {
dbg_print(is_debug_on, "Failed to get chip version form file name: %s.\n", name);
return firmware_error_type(FIRMWARE_ACTION_CHECK, info);
}
strncpy(info->version, start,
(tmp - start > FIRMWARE_NAME_LEN - 1) ? (FIRMWARE_NAME_LEN - 1) : (tmp - start));
/* finish checking */
if (strcmp(tmp, ".vme") != 0) {
dbg_print(is_debug_on, "The file format is wrong: %s.\n", name);
return firmware_error_type(FIRMWARE_ACTION_CHECK, info);
}
return FIRMWARE_SUCCESS;
}
/* check the file information to determine whether the file can be used in the device */
static int firmware_check_file_info(name_info_t *info)
{
int ret;
char card_name[FIRMWARE_NAME_LEN];
dbg_print(is_debug_on, "Check file info.\n");
/* get card name */
mem_clear(card_name, FIRMWARE_NAME_LEN);
ret = firmware_get_card_name(card_name, FIRMWARE_NAME_LEN);
if (ret != FIRMWARE_SUCCESS) {
dbg_print(is_debug_on, "Failed to get card name.(%s)\n", info->card_name);
return firmware_error_type(FIRMWARE_ACTION_CHECK, info);
}
/* check card name */
dbg_print(is_debug_on, "The card name: %s, the file card name: %s.\n",
card_name, info->card_name);
if (strcmp(card_name, info->card_name) != 0) {
dbg_print(is_debug_on, "The file card name %s is wrong.(real: %s)\n",
info->card_name, card_name);
return firmware_error_type(FIRMWARE_ACTION_CHECK, info);
}
/* check type */
if (info->type != FIRMWARE_CPLD && info->type != FIRMWARE_FPGA) {
dbg_print(is_debug_on, "The file type %d is wrong.(cpld %d, fpga %d)\n",
info->type, FIRMWARE_CPLD, FIRMWARE_FPGA);
return firmware_error_type(FIRMWARE_ACTION_CHECK, info);
}
/* check slot */
if (info->slot < 1 || info->slot > FIRMWARE_MAX_SLOT_NUM) {
dbg_print(is_debug_on, "The file slot %d is wrong.\n", info->slot);
return firmware_error_type(FIRMWARE_ACTION_CHECK, info);
}
dbg_print(is_debug_on, "Success check file info.\n");
return FIRMWARE_SUCCESS;
}
static void firmware_get_dev_file_name(name_info_t *info, char *file_name, int len)
{
if (info->type == FIRMWARE_CPLD) {
snprintf(file_name, len, "/dev/firmware_cpld_ispvme%d", info->slot - 1);
} else if (info->type == FIRMWARE_FPGA) {
snprintf(file_name, len, "/dev/firmware_fpga_ispvme%d", info->slot - 1);
} else {
snprintf(file_name, len, "/dev/firmware_ispvme%d", info->slot - 1);
}
}
static void firmware_set_driver_debug(int fd)
{
int ret;
if (is_debug_on == DEBUG_ALL_ON || is_debug_on == DEBUG_KERN_ON) {
ret = ioctl(fd, FIRMWARE_SET_DEBUG_ON, NULL);
if (ret < 0) {
dbg_print(is_debug_on, "Failed to set driver debug on.\n");
} else {
dbg_print(is_debug_on, "Open driver debug.\n");
}
} else if (is_debug_on == DEBUG_OFF) {
ret = ioctl(fd, FIRMWARE_SET_DEBUG_OFF, NULL);
if (ret < 0) {
dbg_print(is_debug_on, "Failed to set driver debug off.\n");
} else {
dbg_print(is_debug_on, "OFF driver debug.\n");
}
} else {
dbg_print(is_debug_on, "Ignore driver debug.\n");
}
}
static int firmware_check_chip_name(int fd, name_info_t *info)
{
return FIRMWARE_SUCCESS;
}
static int firmware_check_chip_verison(int fd, name_info_t *info)
{
return FIRMWARE_SUCCESS;
}
static int firmware_get_file_size(char *file_name, int *size)
{
int ret;
struct stat buf;
ret = stat(file_name, &buf);
if (ret < 0) {
return FIRMWARE_FAILED;
}
if (buf.st_size < 0) {
return FIRMWARE_FAILED;
}
*size = buf.st_size;
return FIRMWARE_SUCCESS;
}
static int firmware_get_file_info(char *file_name, char *buf, int size)
{
FILE *fp;
int len;
fp = fopen(file_name, "r");
if (fp == NULL) {
return FIRMWARE_FAILED;
}
len = fread(buf, size, 1, fp);
if (len < 0) {
fclose(fp);
return FIRMWARE_FAILED;
}
fclose(fp);
return FIRMWARE_SUCCESS;
}
static int firmware_upgrade_info(int fd, char *buf, int size)
{
return FIRMWARE_SUCCESS;
}
/* upgrade CPLD */
static int firmware_upgrade(char *dir, char *file_name, name_info_t *info)
{
return FIRMWARE_SUCCESS;
}
static int firmware_upgrade_file(char *dir, char *file_name)
{
int ret, argc;
name_info_t info;
char *argv[2];
char tmp_file[FIRMWARE_FILE_DIR_LEN];
mem_clear(&info, sizeof(name_info_t));
ret = firmware_parse_file_name(file_name, &info);
if (ret != FIRMWARE_SUCCESS) {
dbg_print(is_debug_on, "Failed to parse file name: %s\n", file_name);
return ret;
}
dbg_print(is_debug_on, "The file name parse:(%s) \n"
" card name: %s, \n"
" type : %d, \n"
" slot : %d, \n"
" chip name: %s \n"
" version : %s \n",
file_name, info.card_name, info.type, info.slot, info.chip_name, info.version);
ret = firmware_check_file_info(&info);
if (ret != FIRMWARE_SUCCESS) {
dbg_print(is_debug_on, "Failed to check file name: %s\n", file_name);
return ret;
}
/* get the information of upgrade file */
mem_clear(tmp_file, FIRMWARE_FILE_DIR_LEN);
if (dir != NULL) {
snprintf(tmp_file, FIRMWARE_FILE_DIR_LEN - 1, "%s/%s", dir, file_name);
} else {
snprintf(tmp_file, FIRMWARE_FILE_DIR_LEN - 1, "%s", file_name);
}
argc = 2;
argv[1] = tmp_file;
ret = ispvme_main(argc, (char **)&argv);
if (ret != FIRMWARE_SUCCESS){
dbg_print(is_debug_on, "Failed to upgrade file name: %s\n", file_name);
}
return ret;
}
static int firmware_upgrade_set_gpio_info(int slot)
{
firmware_card_info_t *hw_info;
cmd_info_t cmd_info;
firmware_upg_gpio_info_t *gpio_info;
int ret;
int fd;
int dev_type;
int my_slot;
ret = 0;
dev_type = drv_get_my_dev_type();
fd = open("/dev/firmware_cpld_ispvme0", O_RDWR);
if (fd < 0) {
dbg_print(is_debug_on, "%s can't open device\r\n", __func__);
return -1;
}
hw_info = firmware_get_card_info(dev_type);
if (hw_info == NULL) {
dbg_print(is_debug_on, "card type 0x%x don't support firmware.\n", dev_type);
ret = -1;
goto gpio_info_err;
}
if (slot >= hw_info->slot_num) {
dbg_print(is_debug_on, "slot %d is too large, support slot num %d.\n", slot, hw_info->slot_num);
ret = -1;
goto gpio_info_err;
}
gpio_info = &(hw_info->gpio_info[slot]);
cmd_info.size = sizeof(firmware_upg_gpio_info_t);
cmd_info.data = (void *)gpio_info;
dbg_print(is_debug_on, "slot = %d, gpio_info[jtag_en:%d select:%d tck:%d tdi:%d tdo=%d tms=%d]\n",slot, \
gpio_info->jtag_en, gpio_info->select,gpio_info->tck,gpio_info->tdi,gpio_info->tdo,gpio_info->tms);
ret = ioctl(fd, FIRMWARE_SET_GPIO_INFO, &cmd_info);
gpio_info_err:
if (ret < 0) {
dbg_print(is_debug_on, "Failed due to:set gpio info.\n");
}
close(fd);
return ret;
}
/**
* argv[1]: file name
* argv[2]: type
* argv[3]: slot number
* argv[4]: chip name
*/
static int firmware_upgrade_one_file(int argc, char *argv[])
{
int ret;
name_info_t info;
char tmp[FIRMWARE_FILE_DIR_LEN];
mem_clear(&info, sizeof(name_info_t));
info.slot = strtoul(argv[3], NULL, 10);
strncpy(info.chip_name, argv[4], FIRMWARE_NAME_LEN - 1);
if (strcmp(argv[2], FIRMWARE_CPLD_NAME) == 0) { /* CPLD upgrade */
if(is_vme_file(argv[1]) == 1){ /* VME upgrade file */
dbg_print(is_debug_on, "vme file\n");
info.type = FIRMWARE_CPLD;
ret = firmware_upgrade_set_gpio_info(info.slot);
if (ret < 0) {
goto upgrade_err;
}
ret = ispvme_main(2, argv);
}
else if(is_vme_file(argv[1]) == 0){ /* bin upgrade file */
dbg_print(is_debug_on, "bin file\n");
mem_clear(tmp, FIRMWARE_FILE_DIR_LEN);
snprintf(tmp, FIRMWARE_FILE_DIR_LEN, "firmware_upgrade_bin %s %s %s %s", argv[1], argv[2], argv[3], argv[4]);
ret = system(tmp);
}
else{
dbg_print(is_debug_on, "unknow file\n");
return FIRMWARE_FAILED;
}
}
else if (strcmp(argv[2], FIRMWARE_FPGA_NAME) == 0) { /* FPGA upgrade */
info.type = FIRMWARE_FPGA;
ret = dfd_fpga_upgrade_do_upgrade(argv[1]);
} else {
dbg_print(is_debug_on, "Failed to get upgrade type: %s.\n", argv[2]);
return ERR_FW_UPGRADE;
}
upgrade_err:
if (ret != FIRMWARE_SUCCESS){
dbg_print(is_debug_on, "Failed to upgrade: %s.\n", argv[1]);
}
return ret;
}
static void firmware_get_err_type(int err, int *real_err)
{
int tmp_err;
tmp_err = *real_err;
if (tmp_err == err) {
return;
}
switch (err) {
case ERR_FW_DO_CPLD_UPGRADE:
case ERR_FW_DO_FPGA_UPGRADE:
if (tmp_err == ERR_FW_CHECK_CPLD_UPGRADE
|| tmp_err == ERR_FW_CHECK_FPGA_UPGRADE
|| tmp_err == FIRMWARE_SUCCESS || tmp_err == ERR_FW_UPGRADE) {
tmp_err = err;
}
break;
case ERR_FW_CHECK_CPLD_UPGRADE:
case ERR_FW_CHECK_FPGA_UPGRADE:
if (tmp_err == FIRMWARE_SUCCESS || tmp_err == ERR_FW_UPGRADE) {
tmp_err = err;
}
break;
case ERR_FW_UPGRADE:
if (tmp_err == FIRMWARE_SUCCESS) {
tmp_err = err;
}
break;
case FIRMWARE_SUCCESS:
break;
default:
return;
}
*real_err = tmp_err;
return;
}
/* argv[1]: Pathname */
static int firmware_upgrade_one_dir(int argc, char *argv[])
{
int ret, real_ret;
int flag;
DIR *dirp;
struct dirent *dp;
char *dir;
dir = argv[1];
dirp = opendir(dir);
if (dirp == NULL) {
dbg_print(is_debug_on, "Failed to open the dir: %s.\n", dir);
return ERR_FW_UPGRADE;
}
ret = ERR_FW_UPGRADE;
real_ret = FIRMWARE_SUCCESS;
flag = 0;
for (;;) {
/* read the pathname of the file */
dp = readdir(dirp);
if (dp == NULL) {
break;
}
dbg_print(is_debug_on, "The file name: %s.\n", dp->d_name);
/* check whether it is a file */
if (firmware_check_file_is_dir(dir, dp->d_name) != 0) {
continue;
}
dbg_print(is_debug_on, "\n=========== Start: %s ===========\n", dp->d_name);
/* upgrade a upgrade file */
ret = firmware_upgrade_file(dir, dp->d_name);
if (ret != FIRMWARE_SUCCESS) {
firmware_get_err_type(ret, &real_ret);
dbg_print(is_debug_on, "Failed to upgrade the file: %s.(%d, %d)\n", dp->d_name, ret, real_ret);
} else {
flag = 1;
dbg_print(is_debug_on, "Upgrade the file: %s success.\n", dp->d_name);
}
dbg_print(is_debug_on, "=========== End: %s ===========\n", dp->d_name);
}
if (flag == 1 && (real_ret == ERR_FW_CHECK_CPLD_UPGRADE || real_ret == ERR_FW_CHECK_FPGA_UPGRADE)) {
real_ret = FIRMWARE_SUCCESS;
}
if (real_ret != FIRMWARE_SUCCESS) {
dbg_print(is_debug_on, "Failed to upgrade: %s.\n", dir);
} else {
dbg_print(is_debug_on, "Upgrade success: %s.\n", dir);
}
closedir(dirp);
return real_ret;
}
/**
* argv[1]: file name
* argv[2]: type
* argv[3]: slot number
*/
static int firmware_upgrade_read_chip(int argc, char *argv[])
{
return FIRMWARE_SUCCESS;
}
static int firmware_upgrade_test_fpga(int argc, char *argv[])
{
int ret;
char tmp1[128];
char tmp2[128];
if ((strcmp(argv[1], FIRMWARE_FPGA_NAME) != 0)
|| (strcmp(argv[2], FIRMWARE_FPGA_TEST) != 0)) {
snprintf(tmp1, sizeof(tmp1), "%s", argv[1]);
snprintf(tmp2, sizeof(tmp2), "%s", argv[2]);
printf( "fpga test:Failed to Input ERR Parm, argv[1]:%s, agrv[2]:%s\n", tmp1,tmp2);
return FIRMWARE_FAILED;
}
ret = dfd_fpga_upgrade_test();
return ret;
}
static int firmware_upgrade_test_chip(int argc, char *argv[])
{
int ret,dev_type,slot;
int err_ret=0;
firmware_card_info_t *hw_info;
char tmp1[128];
char tmp2[128];
if ((strcmp(argv[1], FIRMWARE_CPLD_NAME) != 0)
|| (strcmp(argv[2], FIRMWARE_CPLD_TEST) != 0)) {
snprintf(tmp1, sizeof(tmp1), "%s", argv[1]);
snprintf(tmp2, sizeof(tmp2), "%s", argv[2]);
printf( "gpio test:Failed to Input ERR Parm, argv[1]:%s, agrv[2]:%s\n", tmp1, tmp2);
return FIRMWARE_FAILED;
}
dev_type = drv_get_my_dev_type(); /* get the type of card first */
if (dev_type < 0) {
printf("gpio test:drv_get_my_dev_type failed ret 0x%x.\n", dev_type);
return FIRMWARE_FAILED;
}
hw_info = firmware_get_card_info(dev_type); /* get the detail information of card */
if (hw_info == NULL) {
printf( "gpio test:card type 0x%x don't support firmware.\n", dev_type);
return FIRMWARE_FAILED;
}
for(slot = 0; slot < hw_info->slot_num; slot++){
ret = firmware_upgrade_set_gpio_info(slot); /* set GPIO information */
if(ret < 0){
err_ret++;
printf( "gpio test:Failed to set gpio info,dev_type 0x%x,slot %d\n", dev_type, slot);
continue;
}
ret = ispvme_test(); /* GPIO path test */
if(ret != 0){
err_ret++;
printf("gpio test:ispvme_test failed,dev_type 0x%x,slot %d\n", dev_type, slot);
}
}
if(err_ret != 0)
return FIRMWARE_FAILED;
return FIRMWARE_SUCCESS;
}
int main(int argc, char *argv[])
{
int ret;
is_debug_on = firmware_upgrade_debug();
if (argc != 2 && argc != 5 && argc != 4 && argc != 3 && argc != 6) {
printf("Use:\n");
printf(" upgrade dir : firmware_upgrade_ispvme dir\n");
printf(" upgrade file : firmware_upgrade_ispvme file type slot chip_name\n");
printf(" read chip : firmware_upgrade_ispvme file type slot\n");
dbg_print(is_debug_on, "Failed to upgrade the number of argv: %d.\n", argc);
return ERR_FW_UPGRADE;
}
#if 0
ret = dev_drv_init();
if (ret) {
dbg_print(is_debug_on, "failed to init dfd ret %d.", ret);
return ERR_FW_UPGRADE;
}
#endif
/* dump fpga flash operation */
if (argc == 6) {
if (strcmp(argv[1], "fpga_dump_flash") == 0) {
ret = dfd_fpga_upgrade_dump_flash(argc, argv);
printf("fpga_dump_flash ret %d.\n", ret);
return FIRMWARE_SUCCESS;
} else {
printf("Not support, please check your cmd.\n");
return FIRMWARE_SUCCESS;
}
}
/* upgrade individual files */
if (argc == 5) {
printf("+================================+\n");
printf("|Begin to upgrade, please wait...|\n");
ret = firmware_upgrade_one_file(argc, argv);
if (ret != FIRMWARE_SUCCESS) {
if(strcmp(argv[2], FIRMWARE_CPLD_NAME) == 0)
printf("| CPLD Upgrade failed! |\n");
else if(strcmp(argv[2], FIRMWARE_FPGA_NAME) == 0)
printf("| FPGA Upgrade failed! |\n");
else
printf("| Failed to get upgrade type! |\n");
printf("+================================+\n");
dbg_print(is_debug_on, "Failed to upgrade a firmware file: %s.\n", argv[1]);
return ret;
}
if(strcmp(argv[2], FIRMWARE_CPLD_NAME) == 0)
printf("| CPLD Upgrade succeeded! |\n");
else
printf("| FPGA Upgrade succeeded! |\n");
printf("+================================+\n");
return FIRMWARE_SUCCESS;
}
if (argc == 2) {
printf("+================================+\n");
printf("|Begin to upgrade, please wait...|\n");
ret = firmware_upgrade_one_dir(argc, argv);
if (ret != FIRMWARE_SUCCESS) {
printf("| Upgrade failed! |\n");
printf("+================================+\n");
dbg_print(is_debug_on, "Failed to upgrade a firmware dir: %s.\n", argv[1]);
return ret;
}
printf("| Upgrade succeeded! |\n");
printf("+================================+\n");
return FIRMWARE_SUCCESS;
}
if (argc == 4) {
ret = firmware_upgrade_read_chip(argc, argv);
if (ret != FIRMWARE_SUCCESS) {
dbg_print(is_debug_on, "Failed to read chip: %s.\n", argv[1]);
return ret;
}
return FIRMWARE_SUCCESS;
}
if (argc == 3) {
if (strcmp(argv[1], FIRMWARE_FPGA_NAME) == 0) {
ret = firmware_upgrade_test_fpga(argc, argv);
if (ret != FIRMWARE_SUCCESS) {
printf("+=================+\n");
printf("| FPGA TEST FAIL! |\n");
printf("+=================+\n");
return FIRMWARE_FAILED;
} else {
printf("+=================+\n");
printf("| FPGA TEST PASS! |\n");
printf("+=================+\n");
return FIRMWARE_SUCCESS;
}
} else {
ret = firmware_upgrade_test_chip(argc, argv);
if (ret != FIRMWARE_SUCCESS) {
printf("+=================+\n");
printf("| GPIO TEST FAIL! |\n");
printf("+=================+\n");
return FIRMWARE_FAILED;
} else {
printf("+=================+\n");
printf("| GPIO TEST PASS! |\n");
printf("+=================+\n");
return FIRMWARE_SUCCESS;
}
}
}
return ERR_FW_UPGRADE;
}

View File

@ -1,249 +0,0 @@
/*********************************************************************************
* Lattice Semiconductor Corp. Copyright 2000-2008
*
* This is the hardware.c of ispVME V12.1 for JTAG programmable devices.
* All the functions requiring customization are organized into this file for
* the convinience of porting.
*********************************************************************************/
/*********************************************************************************
* Revision History:
*
* 09/11/07 NN Type cast mismatch variables
* 09/24/07 NN Added calibration function.
* Calibration will help to determine the system clock frequency
* and the count value for one micro-second delay of the target
* specific hardware.
* Modified the ispVMDelay function
* Removed Delay Percent support
* Moved the sclock() function from ivm_core.c to hardware.c
*********************************************************************************/
/* #include <conio.h> */
#include <stdint.h>
#include <linux/types.h>
#include "common.h"
/********************************************************************************
* Declaration of global variables
*
*********************************************************************************/
unsigned char g_siIspPins = 0x00; /*Keeper of JTAG pin state*/
unsigned short g_usInPort = 0x379; /*Address of the TDO pin*/
unsigned short g_usOutPort = 0x378; /*Address of TDI, TMS, TCK pin*/
unsigned short g_usCpu_Frequency = 1000; /*Enter your CPU frequency here, unit in MHz.*/
/*********************************************************************************
* This is the definition of the bit locations of each respective
* signal in the global variable g_siIspPins.
*
* NOTE: Users must add their own implementation here to define
* the bit location of the signal to target their hardware.
* The example below is for the Lattice download cable on
* on the parallel port.
*
*********************************************************************************/
#if 0
const unsigned char g_ucPinTDI = JTAG_TDI; /* Bit address of TDI */
const unsigned char g_ucPinTCK = JTAG_TCK; /* Bit address of TCK */
const unsigned char g_ucPinTMS = JTAG_TMS; /* Bit address of TMS */
const unsigned char g_ucPinENABLE = JTAG_ENABLE; /* Bit address of ENABLE */
const unsigned char g_ucPinTRST = JTAG_TRST; /* Bit address of TRST */
const unsigned char g_ucPinTDO = JTAG_TDO; /* Bit address of TDO*/
#endif
int g_file_fd;
/***************************************************************
*
* Functions declared in hardware.c module.
*
***************************************************************/
void writePort(unsigned char a_ucPins, unsigned char a_ucValue);
unsigned char readPort();
void sclock();
void ispVMDelay(unsigned short a_usTimeDelay);
void calibration(void);
/********************************************************************************
* writePort
* To apply the specified value to the pins indicated. This routine will
* be modified for specific systems.
* As an example, this code uses the IBM-PC standard Parallel port, along with the
* schematic shown in Lattice documentation, to apply the signals to the
* JTAG pins.
*
* PC Parallel port pin Signal name Port bit address
* 2 g_ucPinTDI 1
* 3 g_ucPinTCK 2
* 4 g_ucPinTMS 4
* 5 g_ucPinENABLE 8
* 6 g_ucPinTRST 16
* 10 g_ucPinTDO 64
*
* Parameters:
* - a_ucPins, which is actually a set of bit flags (defined above)
* that correspond to the bits of the data port. Each of the I/O port
* bits that drives an isp programming pin is assigned a flag
* (through a #define) corresponding to the signal it drives. To
* change the value of more than one pin at once, the flags are added
* together, much like file access flags are.
*
* The bit flags are only set if the pin is to be changed. Bits that
* do not have their flags set do not have their levels changed. The
* state of the port is always manintained in the static global
* variable g_siIspPins, so that each pin can be addressed individually
* without disturbing the others.
*
* - a_ucValue, which is either HIGH (0x01 ) or LOW (0x00 ). Only these two
* values are valid. Any non-zero number sets the pin(s) high.
*
*********************************************************************************/
void writePort(unsigned char a_ucPins, unsigned char a_ucValue)
{
switch (a_ucPins) {
case JTAG_TCK:
ioctl(g_file_fd, FIRMWARE_JTAG_TCK, &a_ucValue);
break;
case JTAG_TDI:
ioctl(g_file_fd, FIRMWARE_JTAG_TDI, &a_ucValue);
break;
case JTAG_TMS:
ioctl(g_file_fd, FIRMWARE_JTAG_TMS, &a_ucValue);
break;
case JTAG_ENABLE:
ioctl(g_file_fd, FIRMWARE_JTAG_EN, &a_ucValue);
break;
case JTAG_TRST:
/* ioctl(g_file_fd, FIRMWARE_JTAG_TRST, &a_ucValue); */
break;
default:
break;
}
}
/*********************************************************************************
*
* readPort
*
* Returns the value of the TDO from the device.
*
**********************************************************************************/
unsigned char readPort()
{
unsigned char ucRet = 0;
ioctl(g_file_fd, FIRMWARE_JTAG_TDO, &ucRet);
return (ucRet);
}
/*********************************************************************************
* sclock
*
* Apply a pulse to TCK.
*
* This function is located here so that users can modify to slow down TCK if
* it is too fast (> 25MHZ). Users can change the IdleTime assignment from 0 to
* 1, 2... to effectively slowing down TCK by half, quarter...
*
*********************************************************************************/
void sclock()
{
unsigned short IdleTime = 0; /* change to > 0 if need to slow down TCK */
unsigned short usIdleIndex = 0;
IdleTime++;
for (usIdleIndex = 0; usIdleIndex < IdleTime; usIdleIndex++) {
writePort(JTAG_TCK, 0x01);
}
for (usIdleIndex = 0; usIdleIndex < IdleTime; usIdleIndex++) {
writePort(JTAG_TCK, 0x00);
}
}
/********************************************************************************
*
* ispVMDelay
*
*
* Users must implement a delay to observe a_usTimeDelay, where
* bit 15 of the a_usTimeDelay defines the unit.
* 1 = milliseconds
* 0 = microseconds
* Example:
* a_usTimeDelay = 0x0001 = 1 microsecond delay.
* a_usTimeDelay = 0x8001 = 1 millisecond delay.
*
* This subroutine is called upon to provide a delay from 1 millisecond to a few
* hundreds milliseconds each time.
* It is understood that due to a_usTimeDelay is defined as unsigned short, a 16 bits
* integer, this function is restricted to produce a delay to 64000 micro-seconds
* or 32000 milli-second maximum. The VME file will never pass on to this function
* a delay time > those maximum number. If it needs more than those maximum, the VME
* file will launch the delay function several times to realize a larger delay time
* cummulatively.
* It is perfectly alright to provide a longer delay than required. It is not
* acceptable if the delay is shorter.
*
* Delay function example--using the machine clock signal of the native CPU------
* When porting ispVME to a native CPU environment, the speed of CPU or
* the system clock that drives the CPU is usually known.
* The speed or the time it takes for the native CPU to execute one for loop
* then can be calculated as follows:
* The for loop usually is compiled into the ASSEMBLY code as shown below:
* LOOP: DEC RA;
* JNZ LOOP;
* If each line of assembly code needs 4 machine cycles to execute,
* the total number of machine cycles to execute the loop is 2 x 4 = 8.
* Usually system clock = machine clock (the internal CPU clock).
* Note: Some CPU has a clock multiplier to double the system clock for
the machine clock.
*
* Let the machine clock frequency of the CPU be F, or 1 machine cycle = 1/F.
* The time it takes to execute one for loop = (1/F ) x 8.
* Or one micro-second = F(MHz)/8;
*
* Example: The CPU internal clock is set to 100Mhz, then one micro-second = 100/8 = 12
*
* The C code shown below can be used to create the milli-second accuracy.
* Users only need to enter the speed of the cpu.
*
**********************************************************************************/
void ispVMDelay(unsigned short a_usTimeDelay)
{
if (a_usTimeDelay & 0x8000) {
a_usTimeDelay &= ~0x8000; /* change it to ms */
usleep(a_usTimeDelay * 1000); /* Use usleep to improve accuracy */
} else
usleep(a_usTimeDelay);
return;
}
/*********************************************************************************
*
* calibration
*
* It is important to confirm if the delay function is indeed providing
* the accuracy required. Also one other important parameter needed
* checking is the clock frequency.
* Calibration will help to determine the system clock frequency
* and the loop_per_micro value for one micro-second delay of the target
* specific hardware.
*
**********************************************************************************/
void calibration(void)
{
/*Apply 2 pulses to TCK.*/
writePort(JTAG_TCK, 0x00);
writePort(JTAG_TCK, 0x01);
writePort(JTAG_TCK, 0x00);
writePort(JTAG_TCK, 0x01);
writePort(JTAG_TCK, 0x00);
/*Delay for 1 millisecond. Pass on 1000 or 0x8001 both = 1ms delay.*/
ispVMDelay(0x8001);
/*Apply 2 pulses to TCK*/
writePort(JTAG_TCK, 0x01);
writePort(JTAG_TCK, 0x00);
writePort(JTAG_TCK, 0x01);
writePort(JTAG_TCK, 0x00);
}

View File

@ -1,21 +0,0 @@
#ifndef __FIRMWARE_UPGRADE_DEBUG_H__
#define __FIRMWARE_UPGRADE_DEBUG_H__
#define DEBUG_INFO_LEN 20
#define DEBUG_FILE "/.firmware_upgrade_debug"
#define DEBUG_ON_ALL "3"
#define DEBUG_ON_KERN "2"
#define DEBUG_ON_INFO "1"
#define DEBUG_OFF_INFO "0"
enum debug_s {
DEBUG_OFF = 0, /* debug off */
DEBUG_APP_ON, /* debug app on */
DEBUG_KERN_ON, /* kernel debug on */
DEBUG_ALL_ON, /* debug app and kernel debug on */
DEBUG_IGNORE, /* ignore debug */
};
extern int firmware_upgrade_debug(void);
#endif /* End of __FIRMWARE_UPGRADE_DEBUG_H__ */

View File

@ -1,119 +0,0 @@
#ifndef __FIRMWARE_APP_H__
#define __FIRMWARE_APP_H__
#include <sys/ioctl.h>
#include <debug_ispvme.h>
#include <string.h>
/* Agreement with PKG_MGMT module */
#define ERR_FW_CHECK_CPLD_UPGRADE (440 - 256)
#define ERR_FW_CHECK_FPGA_UPGRADE (441 - 256)
#define ERR_FW_DO_CPLD_UPGRADE (442 - 256)
#define ERR_FW_DO_FPGA_UPGRADE (443 - 256)
#define ERR_FW_UPGRADE (444 - 256)
#define FIRMWARE_FAILED -1
#define FIRMWARE_SUCCESS 0
#define FIRMWARE_ACTION_CHECK 0
#define FIRMWARE_ACTION_UPGRADE 1
#define mem_clear(data, size) memset((data), 0, (size))
#define dbg_print(debug, fmt, arg...) \
if (debug == DEBUG_APP_ON || debug == DEBUG_ALL_ON) \
{ do{printf(fmt,##arg);} while(0); }
#define FIRMWARE_FILE_DIR_LEN 128
#define FIRMWARE_NAME_LEN 48
#define FIRMWARE_MAX_SLOT_NUM 32
#define FIRMWARE_CPLD_NAME "cpld"
#define FIRMWARE_FPGA_NAME "fpga"
#define FIRMWARE_CPLD_EPM1270F256 "EPM1270F256"
#define FIRMWARE_CPLD_5M1270 "5M1270"
#define FIRMWARE_CPLD_TEST "test"
#define FIRMWARE_FPGA_TEST "test"
/* ioctl command */
#define FIRMWARE_TYPE 'F'
#define FIRMWARE_JTAG_TDI _IOR(FIRMWARE_TYPE, 0, char)
#define FIRMWARE_JTAG_TDO _IOR(FIRMWARE_TYPE, 1, char)
#define FIRMWARE_JTAG_TCK _IOR(FIRMWARE_TYPE, 2, char)
#define FIRMWARE_JTAG_TMS _IOR(FIRMWARE_TYPE, 3, char)
#define FIRMWARE_JTAG_EN _IOR(FIRMWARE_TYPE, 4, char)
#define FIRMWARE_SET_DEBUG_ON _IOW(FIRMWARE_TYPE, 5, int) /* debug on */
#define FIRMWARE_SET_DEBUG_OFF _IOW(FIRMWARE_TYPE, 6, int) /* debug off */
#define FIRMWARE_SET_GPIO_INFO _IOR(FIRMWARE_TYPE, 7, int) /* GPIO info */
#define FIRMWARE_MAX_SUB_SLOT_NUM (8)
#define FIRMWARE_MAX_CARD_SLOT_NUM ((FIRMWARE_MAX_SUB_SLOT_NUM) + (1))/* max slot num */
#define FIRMWARE_CARD_NAME_MAX_LEN (64)
#define GPIO(p, v, d) { \
.pin = p, \
.val = v, \
.dir = d, \
},
enum firmware_type_s {
FIRMWARE_CPLD = 0,
FIRMWARE_FPGA,
FIRMWARE_OTHER,
};
typedef struct name_info_s {
char card_name[FIRMWARE_NAME_LEN]; /* card name */
int type; /* upgrade file type */
int slot; /* slot number correspoding to upgrade file */
char chip_name[FIRMWARE_NAME_LEN]; /* chip name */
char version[FIRMWARE_NAME_LEN]; /* version */
} name_info_t;
typedef struct cmd_info_s {
int size;
void *data;
} cmd_info_t;
typedef struct gpio_group_s {
int pin;
int val;
int dir;
} gpio_group_t;
typedef struct firmware_upg_gpio_info_s {
int tdi;
int tck;
int tms;
int tdo;
int jtag_en;
int select;
gpio_group_t jtag_5;
gpio_group_t jtag_4;
gpio_group_t jtag_3;
gpio_group_t jtag_2;
gpio_group_t jtag_1;
} firmware_upg_gpio_info_t;
typedef struct firmware_card_info_s {
int dev_type; /* the type of card */
int slot_num;
char card_name[FIRMWARE_CARD_NAME_MAX_LEN];
firmware_upg_gpio_info_t gpio_info[FIRMWARE_MAX_CARD_SLOT_NUM]; /* private data */
} firmware_card_info_t;
typedef enum card_type_e {
RA_B6010_48GT4X = 0X4065,
RA_B6010_48GT4X_R = 0X4065,
} card_type_t;
extern firmware_card_info_t* firmware_get_card_info(int dev_type);
extern int dfd_fpga_upgrade_do_upgrade(char* upg_file);
extern int dfd_fpga_upgrade_test(void);
extern int ispvme_test(void);
extern int ispvme_main(int argc, char *argv[]);
/* External fpga dump interface */
extern int dfd_fpga_upgrade_dump_flash(int argc, char* argv[]);
#endif /* End of __FIRMWARE_APP_H__ */

View File

@ -1,845 +0,0 @@
/**************************************************************
*
* Lattice Semiconductor Corp. Copyright 2008
*
* ispVME Embedded allows programming of Lattice's suite of FPGA
* devices on embedded systems through the JTAG port. The software
* is distributed in source code form and is open to re - distribution
* and modification where applicable.
*
* ispVME Embedded C Source comprised with 3 modules:
* ispvm_ui.c is the module provides input and output support.
* ivm_core.c is the module interpret the VME file(s).
* hardware.c is the module access the JTAG port of the device(s).
*
* The optional module cable.c is for supporting Lattice's parallel
* port ispDOWNLOAD cable on DOS and Windows 95/98 O/S. It can be
* requested from Lattice's ispVMSupport.
*
***************************************************************/
/**************************************************************
*
* Revision History of ispvm_ui.c
*
* 3/6/07 ht Added functions vme_out_char(),vme_out_hex(),
* vme_out_string() to provide output resources.
* Consolidate all printf() calls into the added output
* functions.
*
* 09/11/07 NN Added Global variables initialization
* 09/24/07 NN Added a switch allowing users to do calibration.
* Calibration will help to determine the system clock frequency
* and the count value for one micro-second delay of the target
* specific hardware.
* Removed Delay Percent support
* 11/15/07 NN moved the checking of the File CRC to the end of processing
* 08/28/08 NN Added Calculate checksum support.
***************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <debug_ispvme.h>
#include "vmopcode.h"
#include "common.h"
#define dbg_print(debug, fmt, arg...) \
if (debug == DEBUG_APP_ON || debug == DEBUG_ALL_ON) \
{ do{printf(fmt,##arg);} while(0); }
/***************************************************************
*
* File pointer to the VME file.
*
***************************************************************/
FILE *g_pVMEFile = NULL;
/***************************************************************
*
* Functions declared in this ispvm_ui.c module
*
***************************************************************/
unsigned char GetByte(void);
void vme_out_char(unsigned char charOut);
void vme_out_hex(unsigned char hexOut);
void vme_out_string(char *stringOut);
void ispVMMemManager(signed char cTarget, unsigned short usSize);
void ispVMFreeMem(void);
void error_handler(short a_siRetCode, char *pszMessage);
signed char ispVM(const char *a_pszFilename);
/***************************************************************
*
* Global variables.
*
***************************************************************/
unsigned short g_usPreviousSize = 0;
unsigned short g_usExpectedCRC = 0;
/***************************************************************
*
* External variables and functions declared in ivm_core.c module.
*
***************************************************************/
extern signed char ispVMCode();
extern void ispVMCalculateCRC32(unsigned char a_ucData);
extern void ispVMStart();
extern void ispVMEnd();
extern void ispVMStateMachine(signed char NextState);
extern void writePort(unsigned char a_ucPins, unsigned char a_ucValue);
extern void sclock();
extern unsigned char readPort();
extern unsigned short g_usCalculatedCRC;
extern unsigned short g_usDataType;
extern unsigned char *g_pucOutMaskData,
*g_pucInData,
*g_pucOutData,
*g_pucHIRData,
*g_pucTIRData,
*g_pucHDRData,
*g_pucTDRData,
*g_pucOutDMaskData,
*g_pucIntelBuffer;
extern unsigned char *g_pucHeapMemory;
extern unsigned short g_iHeapCounter;
extern unsigned short g_iHEAPSize;
extern unsigned short g_usIntelDataIndex;
extern unsigned short g_usIntelBufferSize;
extern LVDSPair *g_pLVDSList;
/* 08/28/08 NN Added Calculate checksum support. */
extern unsigned long g_usChecksum;
extern unsigned int g_uiChecksumIndex;
/***************************************************************
*
* External variables and functions declared in hardware.c module.
*
***************************************************************/
extern void calibration(void);
extern unsigned short g_usCpu_Frequency;
static int is_debug_on = -1;
/***************************************************************
*
* Supported VME versions.
*
***************************************************************/
const char *const g_szSupportedVersions[] = { "__VME2.0", "__VME3.0", "____12.0", "____12.1", 0 };
/***************************************************************
*
* GetByte
*
* Returns a byte to the caller. The returned byte depends on the
* g_usDataType register. If the HEAP_IN bit is set, then the byte
* is returned from the HEAP. If the LHEAP_IN bit is set, then
* the byte is returned from the intelligent buffer. Otherwise,
* the byte is returned directly from the VME file.
*
***************************************************************/
char* strlwr(char *str)
{
char *orig = str;
/* process the string */
for (; *str != '\0'; str++)
*str = tolower(*str);
return orig;
}
unsigned char GetByte()
{
unsigned char ucData = 0;
if (g_usDataType & HEAP_IN) {
/***************************************************************
*
* Get data from repeat buffer.
*
***************************************************************/
if (g_iHeapCounter > g_iHEAPSize) {
/***************************************************************
*
* Data over-run.
*
***************************************************************/
return 0xFF;
}
ucData = g_pucHeapMemory[g_iHeapCounter++];
}
else if ( g_usDataType & LHEAP_IN ) {
/***************************************************************
*
* Get data from intel buffer.
*
***************************************************************/
if (g_usIntelDataIndex >= g_usIntelBufferSize) {
/***************************************************************
*
* Data over-run.
*
***************************************************************/
return 0xFF;
}
ucData = g_pucIntelBuffer[g_usIntelDataIndex++];
}
else {
/***************************************************************
*
* Get data from file.
*
***************************************************************/
ucData = (unsigned char)fgetc(g_pVMEFile);
if (feof(g_pVMEFile)) {
/***************************************************************
*
* Reached EOF.
*
***************************************************************/
return 0xFF;
}
/***************************************************************
*
* Calculate the 32-bit CRC if the expected CRC exist.
*
***************************************************************/
if( g_usExpectedCRC != 0)
{
ispVMCalculateCRC32(ucData);
}
}
return (ucData);
}
/***************************************************************
*
* vme_out_char
*
* Send a character out to the output resource if available.
* The monitor is the default output resource.
*
*
***************************************************************/
void vme_out_char(unsigned char charOut)
{
dbg_print(is_debug_on, "%c", charOut);
}
/***************************************************************
*
* vme_out_hex
*
* Send a character out as in hex format to the output resource
* if available. The monitor is the default output resource.
*
*
***************************************************************/
void vme_out_hex(unsigned char hexOut)
{
dbg_print(is_debug_on, "%.2X", hexOut);
}
/***************************************************************
*
* vme_out_string
*
* Send a text string out to the output resource if available.
* The monitor is the default output resource.
*
*
***************************************************************/
void vme_out_string(char *stringOut)
{
if (is_debug_on == -1) {
is_debug_on = firmware_upgrade_debug();
}
dbg_print(is_debug_on, stringOut);
}
/***************************************************************
*
* ispVMMemManager
*
* Allocate memory based on cTarget. The memory size is specified
* by usSize.
*
***************************************************************/
void ispVMMemManager(signed char cTarget, unsigned short usSize)
{
switch (cTarget) {
case XTDI:
case TDI:
if (g_pucInData != NULL) {
if (g_usPreviousSize == usSize) { /*memory exist*/
break;
}
else {
free(g_pucInData);
g_pucInData = NULL;
}
}
g_pucInData = (unsigned char *)malloc(usSize / 8 + 2);
g_usPreviousSize = usSize;
case XTDO:
case TDO:
if (g_pucOutData != NULL) {
if (g_usPreviousSize == usSize) { /*already exist*/
break;
}
else {
free(g_pucOutData);
g_pucOutData = NULL;
}
}
g_pucOutData = (unsigned char *)malloc(usSize / 8 + 2);
g_usPreviousSize = usSize;
break;
case MASK:
if (g_pucOutMaskData != NULL) {
if (g_usPreviousSize == usSize) { /*already allocated*/
break;
}
else {
free(g_pucOutMaskData);
g_pucOutMaskData = NULL;
}
}
g_pucOutMaskData = (unsigned char *)malloc(usSize / 8 + 2);
g_usPreviousSize = usSize;
break;
case HIR:
if (g_pucHIRData != NULL) {
free(g_pucHIRData);
g_pucHIRData = NULL;
}
g_pucHIRData = (unsigned char *)malloc(usSize / 8 + 2);
break;
case TIR:
if (g_pucTIRData != NULL) {
free(g_pucTIRData);
g_pucTIRData = NULL;
}
g_pucTIRData = (unsigned char *)malloc(usSize / 8 + 2);
break;
case HDR:
if (g_pucHDRData != NULL) {
free(g_pucHDRData);
g_pucHDRData = NULL;
}
g_pucHDRData = (unsigned char *)malloc(usSize / 8 + 2);
break;
case TDR:
if (g_pucTDRData != NULL) {
free(g_pucTDRData);
g_pucTDRData = NULL;
}
g_pucTDRData = (unsigned char *)malloc(usSize / 8 + 2);
break;
case HEAP:
if (g_pucHeapMemory != NULL) {
free(g_pucHeapMemory);
g_pucHeapMemory = NULL;
}
g_pucHeapMemory = (unsigned char *)malloc(usSize + 2);
break;
case DMASK:
if (g_pucOutDMaskData != NULL) {
if (g_usPreviousSize == usSize) { /*already allocated*/
break;
}
else {
free(g_pucOutDMaskData);
g_pucOutDMaskData = NULL;
}
}
g_pucOutDMaskData = (unsigned char *)malloc(usSize / 8 + 2);
g_usPreviousSize = usSize;
break;
case LHEAP:
if (g_pucIntelBuffer != NULL) {
free(g_pucIntelBuffer);
g_pucIntelBuffer = NULL;
}
g_pucIntelBuffer = (unsigned char *)malloc(usSize + 2);
break;
case LVDS:
if (g_pLVDSList != NULL) {
free(g_pLVDSList);
g_pLVDSList = NULL;
}
g_pLVDSList = (LVDSPair * )calloc(usSize, sizeof(LVDSPair));
break;
default:
return;
}
}
/***************************************************************
*
* ispVMFreeMem
*
* Free memory that were dynamically allocated.
*
***************************************************************/
void ispVMFreeMem()
{
if (g_pucHeapMemory != NULL) {
free(g_pucHeapMemory);
g_pucHeapMemory = NULL;
}
if (g_pucOutMaskData != NULL) {
free(g_pucOutMaskData);
g_pucOutMaskData = NULL;
}
if (g_pucInData != NULL) {
free(g_pucInData);
g_pucInData = NULL;
}
if (g_pucOutData != NULL) {
free(g_pucOutData);
g_pucOutData = NULL;
}
if (g_pucHIRData != NULL) {
free(g_pucHIRData);
g_pucHIRData = NULL;
}
if (g_pucTIRData != NULL) {
free(g_pucTIRData);
g_pucTIRData = NULL;
}
if (g_pucHDRData != NULL) {
free(g_pucHDRData);
g_pucHDRData = NULL;
}
if (g_pucTDRData != NULL) {
free(g_pucTDRData);
g_pucTDRData = NULL;
}
if (g_pucOutDMaskData != NULL) {
free(g_pucOutDMaskData);
g_pucOutDMaskData = NULL;
}
if (g_pucIntelBuffer != NULL) {
free(g_pucIntelBuffer);
g_pucIntelBuffer = NULL;
}
if (g_pLVDSList != NULL) {
free(g_pLVDSList);
g_pLVDSList = NULL;
}
}
/***************************************************************
*
* error_handler
*
* Reports the error message.
*
***************************************************************/
void error_handler(short a_siRetCode, char *pszMessage)
{
const char *pszErrorMessage[] = { "pass",
"verification fail",
"can't find the file",
"wrong file type",
"file error",
"option error",
"crc verification error" };
strcpy(pszMessage, pszErrorMessage[-a_siRetCode]);
}
/***************************************************************
*
* ispVM
*
* The entry point of the ispVM embedded. If the version and CRC
* are verified, then the VME will be processed.
*
***************************************************************/
signed char ispVM(const char *a_pszFilename)
{
char szFileVersion[9] = { 0 };
signed char cRetCode = 0;
signed char cIndex = 0;
signed char cVersionIndex = 0;
unsigned char ucReadByte = 0;
/***************************************************************
*
* Global variables initialization.
*
* 09/11/07 NN Added
***************************************************************/
g_pucHeapMemory = NULL;
g_iHeapCounter = 0;
g_iHEAPSize = 0;
g_usIntelDataIndex = 0;
g_usIntelBufferSize = 0;
g_usPreviousSize = 0;
/***************************************************************
*
* Open a file pointer to the VME file.
*
***************************************************************/
if ((g_pVMEFile = fopen(a_pszFilename, "rb")) == NULL) {
return VME_FILE_READ_FAILURE;
}
g_usCalculatedCRC = 0;
g_usExpectedCRC = 0;
ucReadByte = GetByte();
//dbg_print(is_debug_on, "data: 0x%x.\n", ucReadByte);
switch (ucReadByte) {
case FILE_CRC:
/***************************************************************
*
* Read and store the expected CRC to do the comparison at the end.
* Only versions 3.0 and higher support CRC protection.
*
***************************************************************/
g_usExpectedCRC = (unsigned char)fgetc(g_pVMEFile);
g_usExpectedCRC <<= 8;
g_usExpectedCRC |= fgetc(g_pVMEFile);
/***************************************************************
*
* Read and store the version of the VME file.
*
***************************************************************/
for (cIndex = 0; cIndex < 8; cIndex++) {
szFileVersion[cIndex] = GetByte();
}
break;
default:
/***************************************************************
*
* Read and store the version of the VME file. Must be version 2.0.
*
***************************************************************/
szFileVersion[0] = (signed char)ucReadByte;
for (cIndex = 1; cIndex < 8; cIndex++) {
szFileVersion[cIndex] = GetByte();
}
break;
}
/***************************************************************
*
* Compare the VME file version against the supported version.
*
***************************************************************/
/* check the file version: the value of 0x03-0x0a */
for (cVersionIndex = 0; g_szSupportedVersions[cVersionIndex] != 0; cVersionIndex++) {
for (cIndex = 0; cIndex < 8; cIndex++) {
if (szFileVersion[cIndex] != g_szSupportedVersions[cVersionIndex][cIndex]) {
cRetCode = VME_VERSION_FAILURE;
break;
}
cRetCode = 0;
}
if (cRetCode == 0) {
/***************************************************************
*
* Found matching version, break.
*
***************************************************************/
break;
}
}
if (cRetCode < 0) {
/***************************************************************
*
* VME file version failed to match the supported versions.
*
***************************************************************/
fclose(g_pVMEFile);
g_pVMEFile = NULL;
return VME_VERSION_FAILURE;
}
/***************************************************************
*
* Enable the JTAG port to communicate with the device.
* Set the JTAG state machine to the Test-Logic/Reset State.
*
***************************************************************/
ispVMStart();
/***************************************************************
*
* Process the VME file.
*
***************************************************************/
cRetCode = ispVMCode();
/***************************************************************
*
* Set the JTAG State Machine to Test-Logic/Reset state then disable
* the communication with the JTAG port.
*
***************************************************************/
ispVMEnd();
fclose(g_pVMEFile);
g_pVMEFile = NULL;
ispVMFreeMem();
/***************************************************************
*
* Compare the expected CRC versus the calculated CRC.
*
***************************************************************/
if (cRetCode == 0 && g_usExpectedCRC != 0 && (g_usExpectedCRC != g_usCalculatedCRC)) {
printf("Expected CRC: 0x%.4X\n", g_usExpectedCRC);
printf("Calculated CRC: 0x%.4X\n", g_usCalculatedCRC);
return VME_CRC_FAILURE;
}
return (cRetCode);
}
/***************************************************************
*
* main
*
***************************************************************/
extern int g_file_fd;
int ispvme_main(int argc, char *argv[])
{
unsigned short iCommandLineIndex = 0;
short siRetCode = 0;
char szExtension[5] = { 0 };
char szCommandLineArg[300] = { 0 };
short sicalibrate = 0;
/* 08/28/08 NN Added Calculate checksum support. */
g_usChecksum = 0;
g_uiChecksumIndex = 0;
g_file_fd = open("/dev/firmware_cpld_ispvme0", O_RDWR);
if (g_file_fd < 0) {
printf("can't open device\r\n");
return -1;
}
vme_out_string(" Lattice Semiconductor Corp.\n");
vme_out_string("\n ispVME(tm) V");
vme_out_string(VME_VERSION_NUMBER);
vme_out_string(" Copyright 1998-2011.\n");
vme_out_string("\nFor daisy chain programming of all in-system programmable devices\n\n");
if (argc < 2) {
vme_out_string("\nUsage: vme [option] vme_file [vme_file]\n");
vme_out_string("Example: vme vme_file1.vme vme_file2.vme\n");
vme_out_string("option -c: do the calibration.\n");
vme_out_string("Example: vme -c\n");
vme_out_string("Example: vme -c vme_file1.vme vme_file2.vme\n");
vme_out_string("\n\n");
close(g_file_fd);
return -1; /* Used by superiors to judge whether the upgrade is successful */
//exit(1);
}
for (iCommandLineIndex = 1; iCommandLineIndex < argc; iCommandLineIndex++) {
strcpy(szCommandLineArg, argv[iCommandLineIndex]);
if (!strcmp(strlwr(szCommandLineArg), "-c") && (iCommandLineIndex == 1)) {
sicalibrate = 1;
} else if (!strcmp(strlwr(szCommandLineArg), "-c") && (iCommandLineIndex != 1)) {
vme_out_string("Error: calibrate option -c must be the first argument\n\n");
close(g_file_fd);
return -1; /* Used by superiors to judge whether the upgrade is successful */
//exit(1);
} else {
strcpy(szExtension, &szCommandLineArg[strlen(szCommandLineArg) - 4]);
strlwr(szExtension);
if (strcmp(szExtension, ".vme")) {
vme_out_string("Error: VME files must end with the extension *.vme\n\n");
close(g_file_fd);
return -1; /* Used by superiors to judge whether the upgrade is successful */
//exit(1);
}
}
}
siRetCode = 0;
if (sicalibrate) {
calibration();
}
for (iCommandLineIndex = 1; iCommandLineIndex < argc; iCommandLineIndex++) { /* Process all VME files sequentially */
strcpy(szCommandLineArg, argv[iCommandLineIndex]);
if (!strcmp(strlwr(szCommandLineArg), "-c") && (iCommandLineIndex == 1)) {
} else if (!strcmp(strlwr(szCommandLineArg), "-checksum")) {
} else {
vme_out_string("Processing virtual machine file (");
vme_out_string(szCommandLineArg);
vme_out_string(")......\n\n");
siRetCode = ispVM(szCommandLineArg);
if (siRetCode < 0) {
break;
}
}
}
if (siRetCode < 0) {
error_handler(siRetCode, szCommandLineArg);
vme_out_string("Failed due to ");
vme_out_string(szCommandLineArg);
vme_out_string("\n\n");
vme_out_string("+=======+\n");
vme_out_string("| FAIL! |\n");
vme_out_string("+=======+\n\n");
} else {
vme_out_string("+=======+\n");
vme_out_string("| PASS! |\n");
vme_out_string("+=======+\n\n");
/* 08/28/08 NN Added Calculate checksum support. */
if (g_usChecksum != 0) {
g_usChecksum &= 0xFFFF;
printf("Data Checksum: %.4X\n\n", (unsigned int)g_usChecksum);
g_usChecksum = 0;
}
}
close(g_file_fd);
return siRetCode; /* Used by superiors to judge whether the upgrade is successful */
//exit(siRetCode);
}
/**
* function:CPLD online upgrade channel test program
* input parameters: None
* output parameters:None
* return: 0 means test successfully -1 means test failed
*/
int ispvme_test(void)
{
int ret = 0;
unsigned char index = 0;
unsigned char indata = 0,outdata = 0;
unsigned char datasize = 8;
unsigned int tmpdata = 0;
char curbit = 0;
int nDevices = 0;
g_file_fd = open("/dev/firmware_cpld_ispvme0", O_RDWR);
if (g_file_fd < 0) {
printf("can't open device\r\n");
return -1;
}
/* go to Shift-IR */
ispVMStart();
ispVMStateMachine(IDLE);
ispVMStateMachine(IRPAUSE);
ispVMStateMachine(SHIFTIR);
/* Send plenty of ones into the IR registers,that makes sure all devices are in BYPASS! */
for (index = 0; index < 100; index++) {
writePort(JTAG_TDI, 1);
sclock();
}
/* exit Shift-IR,and go to Shift-DR */
ispVMStateMachine(IRPAUSE);
ispVMStateMachine(DRPAUSE);
ispVMStateMachine(SHIFTDR);
/* Send plenty of zeros into the DR registers to flush them */
for (index = 0; index < 100; index++) {
writePort(JTAG_TDI, 0);
sclock();
}
/* now send ones until we receive one back,to find out number of device(s) */
for(index = 0; index < 100; index++){
writePort(JTAG_TDI, 1);
sclock();
curbit = readPort();
if(1 == curbit){
nDevices = index + 1;
break;
}
}
/*flush again */
for (index = 0; index < 100; index++) {
writePort(JTAG_TDI, 0);
sclock();
}
/* test data probe */
indata = 0x5a;
for (index = 0; index < datasize + nDevices; index++) {
tmpdata <<= 1;
curbit = readPort();
tmpdata |= curbit;
writePort(JTAG_TDI, ((indata << index) & 0x80) ? 0x01:0x00);
sclock();
}
outdata = (tmpdata & 0xFF);
if(outdata != indata){
ret = -1;
}
/* go to Test-Logic-Reset */
ispVMStateMachine(IDLE);
ispVMStart();
/* close ispvme */
close(g_file_fd);
return ret;
}

View File

@ -1,192 +0,0 @@
/***************************************************************
*
* This is the include file for Lattice Semiconductor's ispVM
* Embedded software application.
*
***************************************************************/
/***************************************************************
*
* VME version.
*
* History:
*
***************************************************************/
#define VME_VERSION_NUMBER "12.2"
/***************************************************************
*
* Maximum declarations.
*
***************************************************************/
#define VMEHEXMAX 60000L /* The hex file is split 60K per file. */
#define SCANMAX 64000L /* The maximum SDR/SIR burst. */
/***************************************************************
*
* Supported JTAG state transitions.
*
***************************************************************/
#define RESET 0x00
#define IDLE 0x01
#define IRPAUSE 0x02
#define DRPAUSE 0x03
#define SHIFTIR 0x04
#define SHIFTDR 0x05
#define DRCAPTURE 0x06
/***************************************************************
*
* Flow control register bit definitions. A set bit indicates
* that the register currently exhibits the corresponding mode.
*
***************************************************************/
#define INTEL_PRGM 0x0001 /* Intelligent programming is in effect. */
#define CASCADE 0x0002 /* Currently splitting large SDR. */
#define REPEATLOOP 0x0008 /* Currently executing a repeat loop. */
#define SHIFTRIGHT 0x0080 /* The next data stream needs a right shift. */
#define SHIFTLEFT 0x0100 /* The next data stream needs a left shift. */
#define VERIFYUES 0x0200 /* Continue if fail is in effect. */
/***************************************************************
*
* DataType register bit definitions. A set bit indicates
* that the register currently holds the corresponding type of data.
*
***************************************************************/
#define EXPRESS 0x0001 /* Simultaneous program and verify. */
#define SIR_DATA 0x0002 /* SIR is the active SVF command. */
#define SDR_DATA 0x0004 /* SDR is the active SVF command. */
#define COMPRESS 0x0008 /* Data is compressed. */
#define TDI_DATA 0x0010 /* TDI data is present. */
#define TDO_DATA 0x0020 /* TDO data is present. */
#define MASK_DATA 0x0040 /* MASK data is present. */
#define HEAP_IN 0x0080 /* Data is from the heap. */
#define LHEAP_IN 0x0200 /* Data is from intel data buffer. */
#define VARIABLE 0x0400 /* Data is from a declared variable. */
#define CRC_DATA 0x0800 /* CRC data is pressent. */
#define CMASK_DATA 0x1000 /* CMASK data is pressent. */
#define RMASK_DATA 0x2000 /* RMASK data is pressent. */
#define READ_DATA 0x4000 /* READ data is pressent. */
#define DMASK_DATA 0x8000 /* DMASK data is pressent. */
/***************************************************************
*
* Pin opcodes.
*
***************************************************************/
#define signalENABLE 0x1C /* ispENABLE pin. */
#define signalTMS 0x1D /* TMS pin. */
#define signalTCK 0x1E /* TCK pin. */
#define signalTDI 0x1F /* TDI pin. */
#define signalTRST 0x20 /* TRST pin. */
/***************************************************************
*
* Supported vendors.
*
***************************************************************/
#define VENDOR 0x56
#define LATTICE 0x01
#define ALTERA 0x02
#define XILINX 0x03
/***************************************************************
*
* Opcode definitions.
*
* Note: opcodes must be unique.
*
***************************************************************/
#define ENDDATA 0x00 /* The end of the current SDR data stream. */
#define RUNTEST 0x01 /* The duration to stay at the stable state. */
#define ENDDR 0x02 /* The stable state after SDR. */
#define ENDIR 0x03 /* The stable state after SIR. */
#define ENDSTATE 0x04 /* The stable state after RUNTEST. */
#define TRST 0x05 /* Assert the TRST pin. */
#define HIR 0x06 /* The sum of the IR bits of the leading devices. */
#define TIR 0x07 /* The sum of the IR bits of the trailing devices. */
#define HDR 0x08 /* The number of leading devices. */
#define TDR 0x09 /* The number of trailing devices. */
#define ispEN 0x0A /* Assert the ispEN pin. */
#define FREQUENCY 0x0B /* The maximum clock rate to run the JTAG state machine. */
#define STATE 0x10 /* Move to the next stable state. */
#define SIR 0x11 /* The instruction stream follows. */
#define SDR 0x12 /* The data stream follows. */
#define TDI 0x13 /* The following data stream feeds into the device. */
#define TDO 0x14 /* The following data stream is compared against the device. */
#define MASK 0x15 /* The following data stream is used as mask. */
#define XSDR 0x16 /* The following data stream is for simultaneous program and verify. */
#define XTDI 0x17 /* The following data stream is for shift in only. It must be stored for the next XSDR. */
#define XTDO 0x18 /* There is not data stream. The data stream was stored from the previous XTDI. */
#define MEM 0x19 /* The maximum memory needed to allocate in order hold one row of data. */
#define WAIT 0x1A /* The duration of delay to observe. */
#define TCK 0x1B /* The number of TCK pulses. */
#define SHR 0x23 /* Set the flow control register for right shift. */
#define SHL 0x24 /* Set the flow control register for left shift. */
#define HEAP 0x32 /* The memory size needed to hold one loop. */
#define REPEAT 0x33 /* The beginning of the loop. */
#define LEFTPAREN 0x35 /* The beginning of data following the loop. */
#define VAR 0x55 /* Plac holder for loop data. */
#define SEC 0x1C /* The delay time in seconds that must be observed. */
#define SMASK 0x1D /* The mask for TDI data. */
#define MAX 0x1E /* The absolute maximum wait time. */
#define ON 0x1F /* Assert the targeted pin. */
#define OFF 0x20 /* Dis-assert the targeted pin. */
#define SETFLOW 0x30 /* Change the flow control register. */
#define RESETFLOW 0x31 /* Clear the flow control register. */
#define CRC 0x47 /* The following data stream is used for CRC calculation. */
#define CMASK 0x48 /* The following data stream is used as mask for CRC calculation. */
#define RMASK 0x49 /* The following data stream is used as mask for read and save. */
#define READ 0x50 /* The following data stream is used for read and save. */
#define ENDLOOP 0x59 /* The end of the repeat loop. */
#define SECUREHEAP 0x60 /* Used to secure the HEAP opcode. */
#define VUES 0x61 /* Support continue if fail. */
#define DMASK 0x62 /* The following data stream is used for dynamic I/O. */
#define COMMENT 0x63 /* Support SVF comments in the VME file. */
#define HEADER 0x64 /* Support header in VME file. */
#define FILE_CRC 0x65 /* Support crc-protected VME file. */
#define LCOUNT 0x66 /* Support intelligent programming. */
#define LDELAY 0x67 /* Support intelligent programming. */
#define LSDR 0x68 /* Support intelligent programming. */
#define LHEAP 0x69 /* Memory needed to hold intelligent data buffer */
#define CONTINUE 0x70 /* Allow continuation. */
#define LVDS 0x71 /* Support LVDS. */
#define ENDVME 0x7F /* End of the VME file. */
#define HIGH 0x80 /* Assert the targeted pin. */
#define LOW 0x81 /* Dis-assert the targeted pin. */
#define ENDFILE 0xFF /* End of file. */
/***************************************************************
*
* ispVM Embedded Return Codes.
*
***************************************************************/
#define VME_VERIFICATION_FAILURE -1
#define VME_FILE_READ_FAILURE -2
#define VME_VERSION_FAILURE -3
#define VME_INVALID_FILE -4
#define VME_ARGUMENT_FAILURE -5
#define VME_CRC_FAILURE -6
/***************************************************************
*
* Type definitions.
*
***************************************************************/
/* Support LVDS */
typedef struct {
unsigned short usPositiveIndex;
unsigned short usNegativeIndex;
unsigned char ucUpdate;
} LVDSPair;

View File

@ -1,210 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
class FantlvException(Exception):
def __init__(self, message='fantlverror', code=-100):
err = 'errcode: {0} message:{1}'.format(code, message)
Exception.__init__(self, err)
self.code = code
self.message = message
class fan_tlv(object):
HEAD_INFO = "\x01\x7e\x01\xf1"
VERSION = 0x01 # E2PROM file init version is 0x01
FLAG = 0x7E # new version E2PROM mark as 0x7E
HW_VER = 0X01 # consists of master version and revised version
TYPE = 0xf1 # hardware type define
TLV_LEN = 00 # vaild data length(16bit)
_FAN_TLV_HDR_LEN = 6
_FAN_TLV_CRC_LEN = 2
_FAN_TLV_TYPE_NAME = 0x02
_FAN_TLV_TYPE_SN = 0x03
_FAN_TLV_TYPE_HW_INFO = 0x05
_FAN_TLV_TYPE_DEV_TYPE = 0x06
_fandecodetime = 0
@property
def dstatus(self):
return self._dstatus
@property
def typename(self):
return self._typename
@property
def typesn(self):
return self._typesn
@property
def typehwinfo(self):
return self._typehwinfo
@property
def typedevtype(self):
return self._typedevtype
@property
def fanbus(self):
return self._fanbus
@property
def fanloc(self):
return self._fanloc
@property
def fandecodetime(self):
return self._fandecodetime
def __init__(self):
self._typename = ""
self._typesn = ""
self._typehwinfo = ""
self._typedevtype = ""
self._dstatus = 0
def strtoarr(self, str):
s = []
if str is not None:
for index in range(len(str)):
s.append(str[index])
return s
def str_to_hex(self,rest_v):
value = 0
for index in range(len(rest_v)):
value |= ord(rest_v[index]) << ((len(rest_v) - index - 1) * 8)
return value
def hex_to_str(self,s):
len_t = len(s)
if len_t % 2 != 0:
return 0
ret = ""
for t in range(0, int(len_t / 2)):
ret += chr(int(s[2 * t:2 * t + 2], 16))
return ret
def generate_fan_value(self):
bin_buffer = [chr(0xff)] * 256
bin_buffer[0] = chr(self.VERSION)
bin_buffer[1] = chr(self.FLAG)
bin_buffer[2] = chr(self.HW_VER)
bin_buffer[3] = chr(self.TYPE)
temp_t = "%08x" % self.typedevtype # handle devtype first
typedevtype_t = self.hex_to_str(temp_t)
total_len = len(self.typename) + len(self.typesn) + \
len(self.typehwinfo) + len(typedevtype_t) + 8
bin_buffer[4] = chr(total_len >> 8)
bin_buffer[5] = chr(total_len & 0x00FF)
index_start = 6
bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_NAME)
bin_buffer[index_start + 1] = chr(len(self.typename))
bin_buffer[index_start + 2: index_start + 2 +
len(self.typename)] = self.strtoarr(self.typename)
index_start = index_start + 2 + len(self.typename)
bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_SN)
bin_buffer[index_start + 1] = chr(len(self.typesn))
bin_buffer[index_start + 2:index_start + 2 +
len(self.typesn)] = self.strtoarr(self.typesn)
index_start = index_start + 2 + len(self.typesn)
bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_HW_INFO)
bin_buffer[index_start + 1] = chr(len(self.typehwinfo))
bin_buffer[index_start + 2:index_start + 2 +
len(self.typehwinfo)] = self.strtoarr(self.typehwinfo)
index_start = index_start + 2 + len(self.typehwinfo)
bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_DEV_TYPE)
bin_buffer[index_start + 1] = chr(len(typedevtype_t))
bin_buffer[index_start + 2:index_start + 2 +
len(typedevtype_t)] = self.strtoarr(typedevtype_t)
index_start = index_start + 2 + len(typedevtype_t)
crcs = fan_tlv.fancrc(''.join(bin_buffer[0:index_start])) # 2bytes checking
bin_buffer[index_start] = chr(crcs >> 8)
bin_buffer[index_start + 1] = chr(crcs & 0x00ff)
# printvalue(bin_buffer)
return bin_buffer
def decode(self, e2):
if e2[0:4] != self.HEAD_INFO:
raise FantlvException("Fan tlv head info error,not fan tlv type", -10)
ret = []
self.VERSION = ord(e2[0])
self.FLAG = ord(e2[1])
self.HW_VER = ord(e2[2])
self.TYPE = ord(e2[3])
self.TLV_LEN = (ord(e2[4]) << 8) | ord(e2[5])
tlv_index = self._FAN_TLV_HDR_LEN
tlv_end = self._FAN_TLV_HDR_LEN + self.TLV_LEN
# check sum
if len(e2) < self._FAN_TLV_HDR_LEN + self.TLV_LEN + 2:
raise FantlvException("Fan tlv eeprom len error!", -2)
sumcrc = fan_tlv.fancrc(e2[0:self._FAN_TLV_HDR_LEN + self.TLV_LEN])
readcrc = ord(e2[self._FAN_TLV_HDR_LEN + self.TLV_LEN]
) << 8 | ord(e2[self._FAN_TLV_HDR_LEN + self.TLV_LEN + 1])
if sumcrc != readcrc:
raise FantlvException("Fan tlv eeprom checksum error!", -1)
else:
self._dstatus = 0
while (tlv_index + 2) < len(e2) and tlv_index < tlv_end:
s = self.decoder(
e2[tlv_index:tlv_index + 2 + ord(e2[tlv_index + 1])])
tlv_index += ord(e2[tlv_index + 1]) + 2
ret.append(s)
return ret
@staticmethod
def fancrc(t):
sum = 0
for index in range(len(t)):
sum += ord(t[index])
return sum
def decoder(self, t):
try:
name = ""
value = ""
_len = ord(t[1])
if ord(t[0]) == self._FAN_TLV_TYPE_NAME:
name = "Product Name"
value = t[2:2 + ord(t[1])]
self._typename = value
elif ord(t[0]) == self._FAN_TLV_TYPE_SN:
name = "serial Number"
value = t[2:2 + ord(t[1])]
self._typesn = value
elif ord(t[0]) == self._FAN_TLV_TYPE_HW_INFO:
name = "hardware info"
value = t[2:2 + ord(t[1])]
self._typehwinfo = value
elif ord(t[0]) == self._FAN_TLV_TYPE_DEV_TYPE:
name = "dev type"
value = "0x"
for c in t[2:2 + ord(t[1])]:
value += "%02X" % (ord(c),)
self._typedevtype = int(value,16)
return {"name": name, "code": ord(t[0]), "value": value,"lens": _len}
except Exception as e:
print(e)
return None
def __str__(self):
formatstr = "VERSION : 0x%02x \n" \
" FLAG : 0x%02x \n" \
" HW_VER : 0x%02x \n" \
" TYPE : 0x%02x \n" \
"typename : %s \n" \
"typesn : %s \n" \
"typehwinfo : %s \n"
return formatstr % (self.VERSION, self.FLAG, self.HW_VER, self.TYPE, self.typename, self.typesn, self.typehwinfo)

View File

@ -1,957 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import collections
from bitarray import bitarray
from datetime import datetime, timedelta
import sys
__all__ = ["FruException", "FruUtil", "BaseArea", "BoardInfoArea", "ProductInfoArea",
"MultiRecordArea", "Field", "ipmifru"]
__DEBUG__ = "N"
class FruException(Exception):
def __init__(self, message='fruerror', code=-100):
err = 'errcode: {0} message:{1}'.format(code, message)
Exception.__init__(self, err)
self.code = code
self.message = message
def e_print(err):
print("ERROR: " + err)
def d_print(debug_info):
if(__DEBUG__ == "Y"):
print(debug_info)
class FruUtil():
@staticmethod
def decodeLength(value):
a = bitarray(8)
a.setall(True)
a[0:1] = 0
a[1:2] = 0
x = ord(a.tobytes())
return x & ord(value)
@staticmethod
def minToData():
starttime = datetime(1996, 1, 1, 0, 0, 0)
endtime = datetime.now()
seconds = (endtime - starttime).total_seconds()
mins = seconds / 60
m = int(round(mins))
return m
@staticmethod
def getTimeFormat():
return datetime.now().strftime('%Y-%m-%d')
@staticmethod
def getTypeLength(value):
if value is None:
return 0
a = bitarray(8)
a.setall(False)
a[0:1] = 1
a[1:2] = 1
x = ord(a.tobytes())
return x | len(value)
@staticmethod
def checksum(b):
result = 0
for i in range(len(b)):
result += ord(b[i])
return (0x100 - (result & 0xff)) & 0xff
class BaseArea(object):
SUGGESTED_SIZE_COMMON_HEADER = 8
SUGGESTED_SIZE_INTERNAL_USE_AREA = 72
SUGGESTED_SIZE_CHASSIS_INFO_AREA = 32
SUGGESTED_SIZE_BOARD_INFO_AREA = 80
SUGGESTED_SIZE_PRODUCT_INFO_AREA = 80
INITVALUE = b'\x00'
resultvalue = INITVALUE * 256
COMMON_HEAD_VERSION = b'\x01'
__childList = None
def __init__(self, name="", size=0, offset=0):
self.__childList = []
self._offset = offset
self.name = name
self._size = size
self._isPresent = False
self._data = b'\x00' * size
self.__dataoffset = 0
@property
def childList(self):
return self.__childList
@childList.setter
def childList(self, value):
self.__childList = value
@property
def offset(self):
return self._offset
@offset.setter
def offset(self, value):
self._offset = value
@property
def size(self):
return self._size
@size.setter
def size(self, value):
self._size = value
@property
def data(self):
return self._data
@data.setter
def data(self, value):
self._data = value
@property
def isPresent(self):
return self._isPresent
@isPresent.setter
def isPresent(self, value):
self._isPresent = value
class InternalUseArea(BaseArea):
pass
class ChassisInfoArea(BaseArea):
pass
class BoardInfoArea(BaseArea):
_boardTime = None
_fields = None
_mfg_date = None
def __str__(self):
formatstr = "version : %x\n" \
"length : %d \n" \
"language : %x \n" \
"mfg_date : %s \n" \
"boardManufacturer : %s \n" \
"boardProductName : %s \n" \
"boardSerialNumber : %s \n" \
"boardPartNumber : %s \n" \
"fruFileId : %s \n"
tmpstr = formatstr % (ord(self.boardversion), self.size,
self.language, self.getMfgRealData(),
self.boardManufacturer, self.boardProductName,
self.boardSerialNumber, self.boardPartNumber,
self.fruFileId)
for i in range(1, 11):
valtmp = "boardextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
tmpstr += "boardextra%d : %s \n" % (i, valtmpval)
else:
break
return tmpstr
def todict(self):
dic = collections.OrderedDict()
dic["boardversion"] = ord(self.boardversion)
dic["boardlength"] = self.size
dic["boardlanguage"] = self.language
dic["boardmfg_date"] = self.getMfgRealData()
dic["boardManufacturer"] = self.boardManufacturer
dic["boardProductName"] = self.boardProductName
dic["boardSerialNumber"] = self.boardSerialNumber
dic["boardPartNumber"] = self.boardPartNumber
dic["boardfruFileId"] = self.fruFileId
for i in range(1, 11):
valtmp = "boardextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
dic[valtmp] = valtmpval
else:
break
return dic
def decodedata(self):
index = 0
self.areaversion = self.data[index]
index += 1
d_print("decode length :%d class size:%d" %
((ord(self.data[index]) * 8), self.size))
index += 2
timetmp = self.data[index: index + 3]
self.mfg_date = ord(timetmp[0]) | (
ord(timetmp[1]) << 8) | (ord(timetmp[2]) << 16)
d_print("decode getMfgRealData :%s" % self.getMfgRealData())
index += 3
templen = FruUtil.decodeLength(self.data[index])
self.boardManufacturer = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardManufacturer:%s" % self.boardManufacturer)
templen = FruUtil.decodeLength(self.data[index])
self.boardProductName = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardProductName:%s" % self.boardProductName)
templen = FruUtil.decodeLength(self.data[index])
self.boardSerialNumber = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardSerialNumber:%s" % self.boardSerialNumber)
templen = FruUtil.decodeLength(self.data[index])
self.boardPartNumber = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardPartNumber:%s" % self.boardPartNumber)
templen = FruUtil.decodeLength(self.data[index])
self.fruFileId = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode fruFileId:%s" % self.fruFileId)
for i in range(1, 11):
valtmp = "boardextra%d" % i
if self.data[index] != chr(0xc1):
templen = FruUtil.decodeLength(self.data[index])
tmpval = self.data[index + 1: index + templen + 1]
setattr(self, valtmp, tmpval)
index += templen + 1
d_print("decode boardextra%d:%s" % (i, tmpval))
else:
break
def recalcute(self):
d_print("boardInfoArea version:%x" % ord(self.boardversion))
d_print("boardInfoArea length:%d" % self.size)
d_print("boardInfoArea language:%x" % self.language)
self.mfg_date = FruUtil.minToData()
d_print("boardInfoArea mfg_date:%x" % self.mfg_date)
self.data = chr(ord(self.boardversion)) + \
chr(self.size / 8) + chr(self.language)
self.data += chr(self.mfg_date & 0xFF)
self.data += chr((self.mfg_date >> 8) & 0xFF)
self.data += chr((self.mfg_date >> 16) & 0xFF)
d_print("boardInfoArea boardManufacturer:%s" % self.boardManufacturer)
typelength = FruUtil.getTypeLength(self.boardManufacturer)
self.data += chr(typelength)
self.data += self.boardManufacturer
d_print("boardInfoArea boardProductName:%s" % self.boardProductName)
self.data += chr(FruUtil.getTypeLength(self.boardProductName))
self.data += self.boardProductName
d_print("boardInfoArea boardSerialNumber:%s" % self.boardSerialNumber)
self.data += chr(FruUtil.getTypeLength(self.boardSerialNumber))
self.data += self.boardSerialNumber
d_print("boardInfoArea boardPartNumber:%s" % self.boardPartNumber)
self.data += chr(FruUtil.getTypeLength(self.boardPartNumber))
self.data += self.boardPartNumber
d_print("boardInfoArea fruFileId:%s" % self.fruFileId)
self.data += chr(FruUtil.getTypeLength(self.fruFileId))
self.data += self.fruFileId
for i in range(1, 11):
valtmp = "boardextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval))
self.data += chr(FruUtil.getTypeLength(valtmpval))
if valtmpval is None:
pass
else:
self.data += valtmpval
else:
break
self.data += chr(0xc1)
if len(self.data) > (self.size - 1):
incr = (len(self.data) - self.size) / 8 + 1
self.size += incr * 8
self.data = self.data[0:1] + chr(self.size / 8) + self.data[2:]
d_print("self data:%d" % len(self.data))
d_print("self size:%d" % self.size)
d_print("adjust size:%d" % (self.size - len(self.data) - 1))
self.data = self.data.ljust((self.size - 1), self.INITVALUE)
# checksum
checksum = FruUtil.checksum(self.data)
d_print("board info checksum:%x" % checksum)
self.data += chr(checksum)
def getMfgRealData(self):
starttime = datetime(1996, 1, 1, 0, 0, 0)
mactime = starttime + timedelta(minutes=self.mfg_date)
return mactime
@property
def language(self):
self._language = 25
return self._language
@property
def mfg_date(self):
return self._mfg_date
@mfg_date.setter
def mfg_date(self, val):
self._mfg_date = val
@property
def boardversion(self):
self._boardversion = self.COMMON_HEAD_VERSION
return self._boardversion
@property
def fruFileId(self):
return self._FRUFileID
@fruFileId.setter
def fruFileId(self, val):
self._FRUFileID = val
@property
def boardPartNumber(self):
return self._boardPartNumber
@boardPartNumber.setter
def boardPartNumber(self, val):
self._boardPartNumber = val
@property
def boardSerialNumber(self):
return self._boardSerialNumber
@boardSerialNumber.setter
def boardSerialNumber(self, val):
self._boardSerialNumber = val
@property
def boardProductName(self):
return self._boradProductName
@boardProductName.setter
def boardProductName(self, val):
self._boradProductName = val
@property
def boardManufacturer(self):
return self._boardManufacturer
@boardManufacturer.setter
def boardManufacturer(self, val):
self._boardManufacturer = val
@property
def boardTime(self):
return self._boardTime
@boardTime.setter
def boardTime(self, val):
self._boardTime = val
@property
def fields(self):
return self._fields
@fields.setter
def fields(self, val):
self._fields = val
class ProductInfoArea(BaseArea):
_productManufacturer = None
_productAssetTag = None
_FRUFileID = None
def __str__(self):
formatstr = "version : %x\n" \
"length : %d \n" \
"language : %x \n" \
"productManufacturer : %s \n" \
"productName : %s \n" \
"productPartModelName: %s \n" \
"productVersion : %s \n" \
"productSerialNumber : %s \n" \
"productAssetTag : %s \n" \
"fruFileId : %s \n"
tmpstr = formatstr % (ord(self.areaversion), self.size,
self.language, self.productManufacturer,
self.productName, self.productPartModelName,
self.productVersion, self.productSerialNumber,
self.productAssetTag, self.fruFileId)
for i in range(1, 11):
valtmp = "productextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
tmpstr += "productextra%d : %s \n" % (i, valtmpval)
else:
break
return tmpstr
def todict(self):
dic = collections.OrderedDict()
dic["productversion"] = ord(self.areaversion)
dic["productlength"] = self.size
dic["productlanguage"] = self.language
dic["productManufacturer"] = self.productManufacturer
dic["productName"] = self.productName
dic["productPartModelName"] = self.productPartModelName
dic["productVersion"] = int(self.productVersion, 16)
dic["productSerialNumber"] = self.productSerialNumber
dic["productAssetTag"] = self.productAssetTag
dic["productfruFileId"] = self.fruFileId
for i in range(1, 11):
valtmp = "productextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
dic[valtmp] = valtmpval
else:
break
return dic
def decodedata(self):
index = 0
self.areaversion = self.data[index] # 0
index += 1
d_print("decode length %d" % (ord(self.data[index]) * 8))
d_print("class size %d" % self.size)
index += 2
templen = FruUtil.decodeLength(self.data[index])
self.productManufacturer = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productManufacturer:%s" % self.productManufacturer)
templen = FruUtil.decodeLength(self.data[index])
self.productName = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productName:%s" % self.productName)
templen = FruUtil.decodeLength(self.data[index])
self.productPartModelName = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productPartModelName:%s" % self.productPartModelName)
templen = FruUtil.decodeLength(self.data[index])
self.productVersion = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productVersion:%s" % self.productVersion)
templen = FruUtil.decodeLength(self.data[index])
self.productSerialNumber = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productSerialNumber:%s" % self.productSerialNumber)
templen = FruUtil.decodeLength(self.data[index])
self.productAssetTag = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productAssetTag:%s" % self.productAssetTag)
templen = FruUtil.decodeLength(self.data[index])
self.fruFileId = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode fruFileId:%s" % self.fruFileId)
for i in range(1, 11):
valtmp = "productextra%d" % i
if self.data[index] != chr(0xc1) and index < self.size - 1:
templen = FruUtil.decodeLength(self.data[index])
if templen == 0:
break
tmpval = self.data[index + 1: index + templen + 1]
d_print("decode boardextra%d:%s" % (i, tmpval))
setattr(self, valtmp, tmpval)
index += templen + 1
else:
break
@property
def productVersion(self):
return self._productVersion
@productVersion.setter
def productVersion(self, name):
self._productVersion = name
@property
def areaversion(self):
self._areaversion = self.COMMON_HEAD_VERSION
return self._areaversion
@areaversion.setter
def areaversion(self, name):
self._areaversion = name
@property
def language(self):
self._language = 25
return self._language
@property
def productManufacturer(self):
return self._productManufacturer
@productManufacturer.setter
def productManufacturer(self, name):
self._productManufacturer = name
@property
def productName(self):
return self._productName
@productName.setter
def productName(self, name):
self._productName = name
@property
def productPartModelName(self):
return self._productPartModelName
@productPartModelName.setter
def productPartModelName(self, name):
self._productPartModelName = name
@property
def productSerialNumber(self):
return self._productSerialNumber
@productSerialNumber.setter
def productSerialNumber(self, name):
self._productSerialNumber = name
@property
def productAssetTag(self):
return self._productAssetTag
@productAssetTag.setter
def productAssetTag(self, name):
self._productAssetTag = name
@property
def fruFileId(self):
return self._FRUFileID
@fruFileId.setter
def fruFileId(self, name):
self._FRUFileID = name
def recalcute(self):
d_print("product version:%x" % ord(self.areaversion))
d_print("product length:%d" % self.size)
d_print("product language:%x" % self.language)
self.data = chr(ord(self.areaversion)) + \
chr(self.size / 8) + chr(self.language)
typelength = FruUtil.getTypeLength(self.productManufacturer)
self.data += chr(typelength)
self.data += self.productManufacturer
self.data += chr(FruUtil.getTypeLength(self.productName))
self.data += self.productName
self.data += chr(FruUtil.getTypeLength(self.productPartModelName))
self.data += self.productPartModelName
self.data += chr(FruUtil.getTypeLength(self.productVersion))
self.data += self.productVersion
self.data += chr(FruUtil.getTypeLength(self.productSerialNumber))
self.data += self.productSerialNumber
self.data += chr(FruUtil.getTypeLength(self.productAssetTag))
if self.productAssetTag is not None:
self.data += self.productAssetTag
self.data += chr(FruUtil.getTypeLength(self.fruFileId))
self.data += self.fruFileId
# whether the extended field exists or not
for i in range(1, 11):
valtmp = "productextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
d_print("boardInfoArea productextra%d:%s" % (i, valtmpval))
self.data += chr(FruUtil.getTypeLength(valtmpval))
if valtmpval is None:
pass
else:
self.data += valtmpval
else:
break
self.data += chr(0xc1)
if len(self.data) > (self.size - 1):
incr = (len(self.data) - self.size) / 8 + 1
self.size += incr * 8
d_print("self.data:%d" % len(self.data))
d_print("self.size:%d" % self.size)
self.data = self.data[0:1] + chr(self.size / 8) + self.data[2:]
self.data = self.data.ljust((self.size - 1), self.INITVALUE)
checksum = FruUtil.checksum(self.data)
d_print("board info checksum:%x" % checksum)
self.data += chr(checksum)
class MultiRecordArea(BaseArea):
pass
class Field(object):
def __init__(self, fieldType="ASCII", fieldData=""):
self.fieldData = fieldData
self.fieldType = fieldType
@property
def data(self):
return self._data
@property
def fieldType(self):
return self._fieldType
@property
def fieldData(self):
return self._fieldData
class ipmifru(BaseArea):
_BoardInfoArea = None
_ProductInfoArea = None
_InternalUseArea = None
_ChassisInfoArea = None
_multiRecordArea = None
_productinfoAreaOffset = BaseArea.INITVALUE
_boardInfoAreaOffset = BaseArea.INITVALUE
_internalUserAreaOffset = BaseArea.INITVALUE
_chassicInfoAreaOffset = BaseArea.INITVALUE
_multiRecordAreaOffset = BaseArea.INITVALUE
_bindata = None
_bodybin = None
_version = BaseArea.COMMON_HEAD_VERSION
_zeroCheckSum = None
_frusize = 256
def __str__(self):
tmpstr = ""
if self.boardInfoArea.isPresent:
tmpstr += "\nboardinfoarea: \n"
tmpstr += self.boardInfoArea.__str__()
if self.productInfoArea.isPresent:
tmpstr += "\nproductinfoarea: \n"
tmpstr += self.productInfoArea.__str__()
return tmpstr
def decodeBin(self, eeprom):
commonHead = eeprom[0:8]
d_print("decode version %x" % ord(commonHead[0]))
if self.COMMON_HEAD_VERSION != commonHead[0]:
raise FruException("HEAD VERSION error,not Fru format!", -10)
if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]):
strtemp = "check header checksum error [cal:%02x data:%02x]" % (
FruUtil.checksum(commonHead[0:7]), ord(commonHead[7]))
raise FruException(strtemp, -3)
if commonHead[1] != self.INITVALUE:
d_print("Internal Use Area is present")
self.internalUseArea = InternalUseArea(
name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA)
self.internalUseArea.isPresent = True
self.internalUserAreaOffset = ord(commonHead[1])
self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: (
self.internalUserAreaOffset * 8 + self.internalUseArea.size)]
if commonHead[2] != self.INITVALUE:
d_print("Chassis Info Area is present")
self.chassisInfoArea = ChassisInfoArea(
name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA)
self.chassisInfoArea.isPresent = True
self.chassicInfoAreaOffset = ord(commonHead[2])
self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: (
self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)]
if commonHead[3] != self.INITVALUE:
self.boardInfoArea = BoardInfoArea(
name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA)
self.boardInfoArea.isPresent = True
self.boardInfoAreaOffset = ord(commonHead[3])
self.boardInfoArea.size = ord(
eeprom[self.boardInfoAreaOffset * 8 + 1]) * 8
d_print("Board Info Area is present size:%d" %
(self.boardInfoArea.size))
self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: (
self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)]
if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]):
strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \
(FruUtil.checksum(
self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:]))
raise FruException(strtmp, -3)
self.boardInfoArea.decodedata()
if commonHead[4] != self.INITVALUE:
d_print("Product Info Area is present")
self.productInfoArea = ProductInfoArea(
name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA)
self.productInfoArea.isPresent = True
self.productinfoAreaOffset = ord(commonHead[4])
d_print("length offset value: %02x" %
ord(eeprom[self.productinfoAreaOffset * 8 + 1]))
self.productInfoArea.size = ord(
eeprom[self.productinfoAreaOffset * 8 + 1]) * 8
d_print("Product Info Area is present size:%d" %
(self.productInfoArea.size))
self.productInfoArea.data = eeprom[self.productinfoAreaOffset * 8: (
self.productinfoAreaOffset * 8 + self.productInfoArea.size)]
if FruUtil.checksum(self.productInfoArea.data[:-1]) != ord(self.productInfoArea.data[-1:]):
strtmp = "check productInfoArea checksum error [cal:%02x data:%02x]" % (
FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:]))
raise FruException(strtmp, -3)
self.productInfoArea.decodedata()
if commonHead[5] != self.INITVALUE:
self.multiRecordArea = MultiRecordArea(
name="MultiRecord record Area ")
d_print("MultiRecord record present")
self.multiRecordArea.isPresent = True
self.multiRecordAreaOffset = ord(commonHead[5])
self.multiRecordArea.data = eeprom[self.multiRecordAreaOffset * 8: (
self.multiRecordAreaOffset * 8 + self.multiRecordArea.size)]
def initDefault(self):
self.version = self.COMMON_HEAD_VERSION
self.internalUserAreaOffset = self.INITVALUE
self.chassicInfoAreaOffset = self.INITVALUE
self.boardInfoAreaOffset = self.INITVALUE
self.productinfoAreaOffset = self.INITVALUE
self.multiRecordAreaOffset = self.INITVALUE
self.PAD = self.INITVALUE
self.zeroCheckSum = self.INITVALUE
self.offset = self.SUGGESTED_SIZE_COMMON_HEADER
self.productInfoArea = None
self.internalUseArea = None
self.boardInfoArea = None
self.chassisInfoArea = None
self.multiRecordArea = None
# self.recalcute()
@property
def version(self):
return self._version
@version.setter
def version(self, name):
self._version = name
@property
def internalUserAreaOffset(self):
return self._internalUserAreaOffset
@internalUserAreaOffset.setter
def internalUserAreaOffset(self, obj):
self._internalUserAreaOffset = obj
@property
def chassicInfoAreaOffset(self):
return self._chassicInfoAreaOffset
@chassicInfoAreaOffset.setter
def chassicInfoAreaOffset(self, obj):
self._chassicInfoAreaOffset = obj
@property
def productinfoAreaOffset(self):
return self._productinfoAreaOffset
@productinfoAreaOffset.setter
def productinfoAreaOffset(self, obj):
self._productinfoAreaOffset = obj
@property
def boardInfoAreaOffset(self):
return self._boardInfoAreaOffset
@boardInfoAreaOffset.setter
def boardInfoAreaOffset(self, obj):
self._boardInfoAreaOffset = obj
@property
def multiRecordAreaOffset(self):
return self._multiRecordAreaOffset
@multiRecordAreaOffset.setter
def multiRecordAreaOffset(self, obj):
self._multiRecordAreaOffset = obj
@property
def zeroCheckSum(self):
return self._zeroCheckSum
@zeroCheckSum.setter
def zeroCheckSum(self, obj):
self._zeroCheckSum = obj
@property
def productInfoArea(self):
return self._ProductInfoArea
@productInfoArea.setter
def productInfoArea(self, obj):
self._ProductInfoArea = obj
@property
def internalUseArea(self):
return self._InternalUseArea
@internalUseArea.setter
def internalUseArea(self, obj):
self.internalUseArea = obj
@property
def boardInfoArea(self):
return self._BoardInfoArea
@boardInfoArea.setter
def boardInfoArea(self, obj):
self._BoardInfoArea = obj
@property
def chassisInfoArea(self):
return self._ChassisInfoArea
@chassisInfoArea.setter
def chassisInfoArea(self, obj):
self._ChassisInfoArea = obj
@property
def multiRecordArea(self):
return self._multiRecordArea
@multiRecordArea.setter
def multiRecordArea(self, obj):
self._multiRecordArea = obj
@property
def bindata(self):
return self._bindata
@bindata.setter
def bindata(self, obj):
self._bindata = obj
@property
def bodybin(self):
return self._bodybin
@bodybin.setter
def bodybin(self, obj):
self._bodybin = obj
def recalcuteCommonHead(self):
self.bindata = ""
self.offset = self.SUGGESTED_SIZE_COMMON_HEADER
d_print("common Header %d" % self.offset)
d_print("fru eeprom size %d" % self._frusize)
if self.internalUseArea is not None and self.internalUseArea.isPresent:
self.internalUserAreaOffset = self.offset / 8
self.offset += self.internalUseArea.size
d_print("internalUseArea is present offset:%d" % self.offset)
if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent:
self.chassicInfoAreaOffset = self.offset / 8
self.offset += self.chassisInfoArea.size
d_print("chassisInfoArea is present offset:%d" % self.offset)
if self.boardInfoArea is not None and self.boardInfoArea.isPresent:
self.boardInfoAreaOffset = self.offset / 8
self.offset += self.boardInfoArea.size
d_print("boardInfoArea is present offset:%d" % self.offset)
d_print("boardInfoArea is present size:%d" %
self.boardInfoArea.size)
if self.productInfoArea is not None and self.productInfoArea.isPresent:
self.productinfoAreaOffset = self.offset / 8
self.offset += self.productInfoArea.size
d_print("productInfoArea is present offset:%d" % self.offset)
if self.multiRecordArea is not None and self.multiRecordArea.isPresent:
self.multiRecordAreaOffset = self.offset / 8
d_print("multiRecordArea is present offset:%d" % self.offset)
if self.internalUserAreaOffset == self.INITVALUE:
self.internalUserAreaOffset = 0
if self.productinfoAreaOffset == self.INITVALUE:
self.productinfoAreaOffset = 0
if self.chassicInfoAreaOffset == self.INITVALUE:
self.chassicInfoAreaOffset = 0
if self.boardInfoAreaOffset == self.INITVALUE:
self.boardInfoAreaOffset = 0
if self.multiRecordAreaOffset == self.INITVALUE:
self.multiRecordAreaOffset = 0
self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset
- self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff
d_print("zerochecksum:%x" % self.zeroCheckSum)
self.data = self.version + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr(
self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + self.INITVALUE + chr(self.zeroCheckSum)
self.bindata = self.data + self.bodybin
totallen = len(self.bindata)
d_print("totallen %d" % totallen)
if (totallen < self._frusize):
self.bindata = self.bindata.ljust(self._frusize, self.INITVALUE)
else:
raise FruException('bin data more than %d' % self._frusize, -2)
def recalcutebin(self):
self.bodybin = ""
if self.internalUseArea is not None and self.internalUseArea.isPresent:
d_print("internalUseArea present")
self.bodybin += self.internalUseArea.data
if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent:
d_print("chassisInfoArea present")
self.bodybin += self.chassisInfoArea.data
if self.boardInfoArea is not None and self.boardInfoArea.isPresent:
d_print("boardInfoArea present")
self.boardInfoArea.recalcute()
self.bodybin += self.boardInfoArea.data
if self.productInfoArea is not None and self.productInfoArea.isPresent:
d_print("productInfoAreapresent")
self.productInfoArea.recalcute()
self.bodybin += self.productInfoArea.data
if self.multiRecordArea is not None and self.multiRecordArea.isPresent:
d_print("multiRecordArea present")
self.bodybin += self.productInfoArea.data
def recalcute(self, fru_eeprom_size = 256):
self._frusize = fru_eeprom_size
self.recalcutebin()
self.recalcuteCommonHead()

View File

@ -1,23 +0,0 @@
# -*- coding: UTF-8 -*-
import os
def get_machine_info():
if not os.path.isfile('/host/machine.conf'):
return None
machine_vars = {}
with open('/host/machine.conf') as machine_file:
for line in machine_file:
tokens = line.split('=')
if len(tokens) < 2:
continue
machine_vars[tokens[0]] = tokens[1].strip()
return machine_vars
def get_platform_info(machine_info):
if machine_info != None:
if 'onie_platform' in machine_info:
return machine_info['onie_platform']
elif 'aboot_platform' in machine_info:
return machine_info['aboot_platform']
return None

View File

@ -1,67 +0,0 @@
# -*- coding: UTF-8 -*-
import logging
from syslog import (
syslog,
openlog,
LOG_WARNING,
LOG_CRIT,
LOG_DEBUG,
LOG_ERR,
LOG_PID,
LOG_INFO,
)
class Logger():
def __init__(self, prefix, filepath=None, syslog=False, dbg_mask=0x0):
self.logger = None
if syslog is False:
if filepath is None:
raise AttributeError("filepath needed")
# init logging
formatter = logging.Formatter( "%(asctime)s %(levelname)s %(filename)s[%(funcName)s][%(lineno)s]: %(message)s")
handler = logging.FileHandler(self.filepath)
handler.setFormatter(formatter)
self.logger = logging.getLogger(__name__)
self.logger.setLevel(logging.DEBUG)
self.logger.addHandler(handler)
self.prefix = prefix
self.use_syslog = syslog
self.dbg_mask = dbg_mask
def info(self, s):
if self.use_syslog:
self._syslog(s, LOG_INFO)
else:
self.logger.info(s)
def debug(self, dbg_lvl, s):
if dbg_lvl & self.dbg_mask:
if self.use_syslog:
self._syslog(s, LOG_DEBUG)
else:
self.logger.debug(s)
def warn(self, s):
if self.use_syslog:
self._syslog(s, LOG_WARNING)
else:
self.logger.warning(s)
def error(self, s):
if self.use_syslog:
self._syslog(s, LOG_ERR)
else:
self.logger.error(s)
def crit(self, s):
if self.use_syslog:
self._syslog(s, LOG_CRIT)
else:
self.logger.critical(s)
def _syslog(self, s, t):
openlog(self.prefix, LOG_PID)
syslog(t, s)

View File

@ -1,774 +0,0 @@
"""smbus2 - A drop-in replacement for smbus-cffi/smbus-python"""
# The MIT License (MIT)
# Copyright (c) 2017 Karl-Petter Lindegaard
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import os
import sys
from fcntl import ioctl
from ctypes import c_uint32, c_uint8, c_uint16, c_char, POINTER, Structure, Array, Union, create_string_buffer, string_at
# Commands from uapi/linux/i2c-dev.h
I2C_SLAVE = 0x0703 # Use this slave address
I2C_SLAVE_FORCE = 0x0706 # Use this slave address, even if it is already in use by a driver!
I2C_FUNCS = 0x0705 # Get the adapter functionality mask
I2C_RDWR = 0x0707 # Combined R/W transfer (one STOP only)
I2C_SMBUS = 0x0720 # SMBus transfer. Takes pointer to i2c_smbus_ioctl_data
I2C_PEC = 0x0708
# SMBus transfer read or write markers from uapi/linux/i2c.h
I2C_SMBUS_WRITE = 0
I2C_SMBUS_READ = 1
# Size identifiers uapi/linux/i2c.h
I2C_SMBUS_QUICK = 0
I2C_SMBUS_BYTE = 1
I2C_SMBUS_BYTE_DATA = 2
I2C_SMBUS_WORD_DATA = 3
I2C_SMBUS_PROC_CALL = 4
I2C_SMBUS_BLOCK_DATA = 5 # This isn't supported by Pure-I2C drivers with SMBUS emulation, like those in RaspberryPi, OrangePi, etc :(
I2C_SMBUS_BLOCK_PROC_CALL = 7 # Like I2C_SMBUS_BLOCK_DATA, it isn't supported by Pure-I2C drivers either.
I2C_SMBUS_I2C_BLOCK_DATA = 8
I2C_SMBUS_BLOCK_MAX = 32
# To determine what functionality is present (uapi/linux/i2c.h)
try:
from enum import IntFlag
except ImportError:
IntFlag = int
class I2cFunc(IntFlag):
"""
These flags identify the operations supported by an I2C/SMBus device.
You can test these flags on your `smbus.funcs`
On newer python versions, I2cFunc is an IntFlag enum, but it
falls back to class with a bunch of int constants on older releases.
"""
I2C = 0x00000001
ADDR_10BIT = 0x00000002
PROTOCOL_MANGLING = 0x00000004 # I2C_M_IGNORE_NAK etc.
SMBUS_PEC = 0x00000008
NOSTART = 0x00000010 # I2C_M_NOSTART
SLAVE = 0x00000020
SMBUS_BLOCK_PROC_CALL = 0x00008000 # SMBus 2.0
SMBUS_QUICK = 0x00010000
SMBUS_READ_BYTE = 0x00020000
SMBUS_WRITE_BYTE = 0x00040000
SMBUS_READ_BYTE_DATA = 0x00080000
SMBUS_WRITE_BYTE_DATA = 0x00100000
SMBUS_READ_WORD_DATA = 0x00200000
SMBUS_WRITE_WORD_DATA = 0x00400000
SMBUS_PROC_CALL = 0x00800000
SMBUS_READ_BLOCK_DATA = 0x01000000
SMBUS_WRITE_BLOCK_DATA = 0x02000000
SMBUS_READ_I2C_BLOCK = 0x04000000 # I2C-like block xfer
SMBUS_WRITE_I2C_BLOCK = 0x08000000 # w/ 1-byte reg. addr.
SMBUS_HOST_NOTIFY = 0x10000000
SMBUS_BYTE = 0x00060000
SMBUS_BYTE_DATA = 0x00180000
SMBUS_WORD_DATA = 0x00600000
SMBUS_BLOCK_DATA = 0x03000000
SMBUS_I2C_BLOCK = 0x0c000000
SMBUS_EMUL = 0x0eff0008
# i2c_msg flags from uapi/linux/i2c.h
I2C_M_RD = 0x0001
# Pointer definitions
LP_c_uint8 = POINTER(c_uint8)
LP_c_uint16 = POINTER(c_uint16)
LP_c_uint32 = POINTER(c_uint32)
#############################################################
# Type definitions as in i2c.h
class i2c_smbus_data(Array):
"""
Adaptation of the i2c_smbus_data union in ``i2c.h``.
Data for SMBus messages.
"""
_length_ = I2C_SMBUS_BLOCK_MAX + 2
_type_ = c_uint8
class union_i2c_smbus_data(Union):
_fields_ = [
("byte", c_uint8),
("word", c_uint16),
("block", i2c_smbus_data)
]
union_pointer_type = POINTER(union_i2c_smbus_data)
class i2c_smbus_ioctl_data(Structure):
"""
As defined in ``i2c-dev.h``.
"""
_fields_ = [
('read_write', c_uint8),
('command', c_uint8),
('size', c_uint32),
('data', union_pointer_type)]
__slots__ = [name for name, type in _fields_]
@staticmethod
def create(read_write=I2C_SMBUS_READ, command=0, size=I2C_SMBUS_BYTE_DATA):
u = union_i2c_smbus_data()
return i2c_smbus_ioctl_data(
read_write=read_write, command=command, size=size,
data=union_pointer_type(u))
#############################################################
# Type definitions for i2c_rdwr combined transactions
class i2c_msg(Structure):
"""
As defined in ``i2c.h``.
"""
_fields_ = [
('addr', c_uint16),
('flags', c_uint16),
('len', c_uint16),
('buf', POINTER(c_char))]
def __iter__(self):
""" Iterator / Generator
:return: iterates over :py:attr:`buf`
:rtype: :py:class:`generator` which returns int values
"""
idx = 0
while idx < self.len:
yield ord(self.buf[idx])
idx += 1
def __len__(self):
return self.len
def __bytes__(self):
return string_at(self.buf, self.len)
def __repr__(self):
return 'i2c_msg(%d,%d,%r)' % (self.addr, self.flags, self.__bytes__())
def __str__(self):
s = self.__bytes__()
if sys.version_info.major >= 3:
s = ''.join(map(chr, s))
return s
@staticmethod
def read(address, length):
"""
Prepares an i2c read transaction.
:param address: Slave address.
:type: address: int
:param length: Number of bytes to read.
:type: length: int
:return: New :py:class:`i2c_msg` instance for read operation.
:rtype: :py:class:`i2c_msg`
"""
arr = create_string_buffer(length)
return i2c_msg(
addr=address, flags=I2C_M_RD, len=length,
buf=arr)
@staticmethod
def write(address, buf):
"""
Prepares an i2c write transaction.
:param address: Slave address.
:type address: int
:param buf: Bytes to write. Either list of values or str.
:type buf: list
:return: New :py:class:`i2c_msg` instance for write operation.
:rtype: :py:class:`i2c_msg`
"""
if sys.version_info.major >= 3:
if type(buf) is str:
buf = bytes(map(ord, buf))
else:
buf = bytes(buf)
else:
if type(buf) is not str:
buf = ''.join([chr(x) for x in buf])
arr = create_string_buffer(buf, len(buf))
return i2c_msg(
addr=address, flags=0, len=len(arr),
buf=arr)
class i2c_rdwr_ioctl_data(Structure):
"""
As defined in ``i2c-dev.h``.
"""
_fields_ = [
('msgs', POINTER(i2c_msg)),
('nmsgs', c_uint32)
]
__slots__ = [name for name, type in _fields_]
@staticmethod
def create(*i2c_msg_instances):
"""
Factory method for creating a i2c_rdwr_ioctl_data struct that can
be called with ``ioctl(fd, I2C_RDWR, data)``.
:param i2c_msg_instances: Up to 42 i2c_msg instances
:rtype: i2c_rdwr_ioctl_data
"""
n_msg = len(i2c_msg_instances)
msg_array = (i2c_msg * n_msg)(*i2c_msg_instances)
return i2c_rdwr_ioctl_data(
msgs=msg_array,
nmsgs=n_msg
)
#############################################################
class SMBus(object):
def __init__(self, bus=None, force=False):
"""
Initialize and (optionally) open an i2c bus connection.
:param bus: i2c bus number (e.g. 0 or 1)
or an absolute file path (e.g. `/dev/i2c-42`).
If not given, a subsequent call to ``open()`` is required.
:type bus: int or str
:param force: force using the slave address even when driver is
already using it.
:type force: boolean
"""
self.fd = None
self.funcs = I2cFunc(0)
if bus is not None:
self.open(bus)
self.address = None
self.force = force
self._force_last = None
def __enter__(self):
"""Enter handler."""
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""Exit handler."""
self.close()
def open(self, bus):
"""
Open a given i2c bus.
:param bus: i2c bus number (e.g. 0 or 1)
or an absolute file path (e.g. '/dev/i2c-42').
:type bus: int or str
:raise TypeError: if type(bus) is not in (int, str)
"""
if isinstance(bus, int):
filepath = "/dev/i2c-{}".format(bus)
elif isinstance(bus, str):
filepath = bus
else:
raise TypeError("Unexpected type(bus)={}".format(type(bus)))
self.fd = os.open(filepath, os.O_RDWR)
self.funcs = self._get_funcs()
def close(self):
"""
Close the i2c connection.
"""
if self.fd:
os.close(self.fd)
self.fd = None
def _set_address(self, address, force=None):
"""
Set i2c slave address to use for subsequent calls.
:param address:
:type address: int
:param force:
:type force: Boolean
"""
force = force if force is not None else self.force
if self.address != address or self._force_last != force:
if force is True:
ioctl(self.fd, I2C_SLAVE_FORCE, address)
else:
ioctl(self.fd, I2C_SLAVE, address)
self.address = address
self._force_last = force
def _get_funcs(self):
"""
Returns a 32-bit value stating supported I2C functions.
:rtype: int
"""
f = c_uint32()
ioctl(self.fd, I2C_FUNCS, f)
return f.value
def write_quick(self, i2c_addr, force=None):
"""
Perform quick transaction. Throws IOError if unsuccessful.
:param i2c_addr: i2c address
:type i2c_addr: int
:param force:
:type force: Boolean
"""
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=0, size=I2C_SMBUS_QUICK)
ioctl(self.fd, I2C_SMBUS, msg)
def read_byte(self, i2c_addr, force=None):
"""
Read a single byte from a device.
:rtype: int
:param i2c_addr: i2c address
:type i2c_addr: int
:param force:
:type force: Boolean
:return: Read byte value
"""
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_READ, command=0, size=I2C_SMBUS_BYTE
)
ioctl(self.fd, I2C_SMBUS, msg)
return msg.data.contents.byte
def write_byte(self, i2c_addr, value, force=None):
"""
Write a single byte to a device.
:param i2c_addr: i2c address
:type i2c_addr: int
:param value: value to write
:type value: int
:param force:
:type force: Boolean
"""
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=value, size=I2C_SMBUS_BYTE
)
ioctl(self.fd, I2C_SMBUS, msg)
def read_byte_data(self, i2c_addr, register, force=None):
"""
Read a single byte from a designated register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to read
:type register: int
:param force:
:type force: Boolean
:return: Read byte value
:rtype: int
"""
val_t = -1
returnmsg=""
try:
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_READ, command=register, size=I2C_SMBUS_BYTE_DATA
)
val_t = ioctl(self.fd, I2C_SMBUS, msg)
except Exception as e:
self.close()
returnmsg = str(e)
if val_t < 0:
return False, returnmsg
else:
return True, msg.data.contents.byte
def write_byte_data(self, i2c_addr, register, value, force=None):
"""
Write a byte to a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to write to
:type register: int
:param value: Byte value to transmit
:type value: int
:param force:
:type force: Boolean
:rtype: None
"""
val_t = -1
returnmsg = ""
try:
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_BYTE_DATA
)
msg.data.contents.byte = value
val_t = ioctl(self.fd, I2C_SMBUS, msg)
except Exception as e:
returnmsg = str(e)
self.close()
if val_t < 0:
return False, returnmsg or ""
else:
return True, ""
def write_byte_data_pec(self, i2c_addr, register, value, force=None):
"""
Write a byte to a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to write to
:type register: int
:param value: Byte value to transmit
:type value: int
:param force:
:type force: Boolean
:rtype: None
"""
val_t = -1
returnmsg = ""
try:
val_t = ioctl(self.fd, I2C_PEC, 1)
if val_t < 0:
raise Exception("set pec mod error")
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_BYTE_DATA
)
msg.data.contents.byte = value
val_t = ioctl(self.fd, I2C_SMBUS, msg)
except Exception as e:
returnmsg = str(e)
self.close()
if val_t < 0:
return False, returnmsg or ""
else:
return True, ""
def read_word_data(self, i2c_addr, register, force=None):
"""
Read a single word (2 bytes) from a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to read
:type register: int
:param force:
:type force: Boolean
:return: 2-byte word
:rtype: int
"""
val_t = -1
returnmsg = ""
try:
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_READ, command=register, size=I2C_SMBUS_WORD_DATA
)
val_t = ioctl(self.fd, I2C_SMBUS, msg)
except Exception as e:
returnmsg = str(e)
self.close()
if val_t < 0:
return False, returnmsg or ""
else:
return True, msg.data.contents.word
def write_word_data_pec(self, i2c_addr, register, value, force=None):
"""
Write a byte to a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to write to
:type register: int
:param value: Word value to transmit
:type value: int
:param force:
:type force: Boolean
:rtype: None
"""
val_t = -1
returnmsg = ""
try:
val_t = ioctl(self.fd, I2C_PEC, 1)
if val_t < 0:
raise Exception("set pec mod error")
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_WORD_DATA
)
msg.data.contents.word = value
val_t = ioctl(self.fd, I2C_SMBUS, msg)
except Exception as e:
returnmsg = str(e)
self.close()
if val_t < 0:
return False, returnmsg or ""
else:
return True, ""
def write_word_data(self, i2c_addr, register, value, force=None):
"""
Write a byte to a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to write to
:type register: int
:param value: Word value to transmit
:type value: int
:param force:
:type force: Boolean
:rtype: None
"""
val_t = -1
returnmsg = ""
try:
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_WORD_DATA
)
msg.data.contents.word = value
val_t = ioctl(self.fd, I2C_SMBUS, msg)
except Exception as e:
returnmsg = str(e)
self.close()
if val_t < 0:
return False, returnmsg or ""
else:
return True, ""
def process_call(self, i2c_addr, register, value, force=None):
"""
Executes a SMBus Process Call, sending a 16-bit value and receiving a 16-bit response
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to read/write to
:type register: int
:param value: Word value to transmit
:type value: int
:param force:
:type force: Boolean
:rtype: int
"""
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_PROC_CALL
)
msg.data.contents.word = value
ioctl(self.fd, I2C_SMBUS, msg)
return msg.data.contents.word
def read_block_data(self, i2c_addr, register, force=None):
"""
Read a block of up to 32-bytes from a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Start register
:type register: int
:param force:
:type force: Boolean
:return: List of bytes
:rtype: list
"""
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_READ, command=register, size=I2C_SMBUS_BLOCK_DATA
)
ioctl(self.fd, I2C_SMBUS, msg)
length = msg.data.contents.block[0]
return msg.data.contents.block[1:length + 1]
def write_block_data(self, i2c_addr, register, data, force=None):
"""
Write a block of byte data to a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Start register
:type register: int
:param data: List of bytes
:type data: list
:param force:
:type force: Boolean
:rtype: None
"""
length = len(data)
if length > I2C_SMBUS_BLOCK_MAX:
raise ValueError("Data length cannot exceed %d bytes" % I2C_SMBUS_BLOCK_MAX)
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_BLOCK_DATA
)
msg.data.contents.block[0] = length
msg.data.contents.block[1:length + 1] = data
ioctl(self.fd, I2C_SMBUS, msg)
def block_process_call(self, i2c_addr, register, data, force=None):
"""
Executes a SMBus Block Process Call, sending a variable-size data
block and receiving another variable-size response
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to read/write to
:type register: int
:param data: List of bytes
:type data: list
:param force:
:type force: Boolean
:return: List of bytes
:rtype: list
"""
length = len(data)
if length > I2C_SMBUS_BLOCK_MAX:
raise ValueError("Data length cannot exceed %d bytes" % I2C_SMBUS_BLOCK_MAX)
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_BLOCK_PROC_CALL
)
msg.data.contents.block[0] = length
msg.data.contents.block[1:length + 1] = data
ioctl(self.fd, I2C_SMBUS, msg)
length = msg.data.contents.block[0]
return msg.data.contents.block[1:length + 1]
def read_i2c_block_data(self, i2c_addr, register, length, force=None):
"""
Read a block of byte data from a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Start register
:type register: int
:param length: Desired block length
:type length: int
:param force:
:type force: Boolean
:return: List of bytes
:rtype: list
"""
if length > I2C_SMBUS_BLOCK_MAX:
raise ValueError("Desired block length over %d bytes" % I2C_SMBUS_BLOCK_MAX)
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_READ, command=register, size=I2C_SMBUS_I2C_BLOCK_DATA
)
msg.data.contents.byte = length
ioctl(self.fd, I2C_SMBUS, msg)
return msg.data.contents.block[1:length + 1]
def write_i2c_block_data(self, i2c_addr, register, data, force=None):
"""
Write a block of byte data to a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Start register
:type register: int
:param data: List of bytes
:type data: list
:param force:
:type force: Boolean
:rtype: None
"""
length = len(data)
if length > I2C_SMBUS_BLOCK_MAX:
raise ValueError("Data length cannot exceed %d bytes" % I2C_SMBUS_BLOCK_MAX)
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_I2C_BLOCK_DATA
)
msg.data.contents.block[0] = length
msg.data.contents.block[1:length + 1] = data
ioctl(self.fd, I2C_SMBUS, msg)
def i2c_rdwr(self, *i2c_msgs):
"""
Combine a series of i2c read and write operations in a single
transaction (with repeated start bits but no stop bits in between).
This method takes i2c_msg instances as input, which must be created
first with :py:meth:`i2c_msg.read` or :py:meth:`i2c_msg.write`.
:param i2c_msgs: One or more i2c_msg class instances.
:type i2c_msgs: i2c_msg
:rtype: None
"""
ioctl_data = i2c_rdwr_ioctl_data.create(*i2c_msgs)
ioctl(self.fd, I2C_RDWR, ioctl_data)
class SMBusWrapper:
"""
Wrapper class around the SMBus.
Deprecated as of version 0.3.0. Please replace with :py:class:`SMBus`.
Enables the user to wrap access to the :py:class:`SMBus` class in a
"with" statement. If auto_cleanup is True (default), the
:py:class:`SMBus` handle will be automatically closed
upon exit of the ``with`` block.
"""
def __init__(self, bus_number=0, auto_cleanup=True, force=False):
"""
:param auto_cleanup: Close bus when leaving scope.
:type auto_cleanup: Boolean
:param force: Force using the slave address even when driver is already using it.
:type force: Boolean
"""
self.bus_number = bus_number
self.auto_cleanup = auto_cleanup
self.force = force
def __enter__(self):
self.bus = SMBus(bus=self.bus_number, force=self.force)
return self.bus
def __exit__(self, exc_type, exc_val, exc_tb):
if self.auto_cleanup:
self.bus.close()

View File

@ -1,32 +0,0 @@
PWD = $(shell pwd)
EXTRA_CFLAGS:= -I$(M)/include
EXTRA_CFLAGS+= -Wall
KVERSION ?= $(shell uname -r)
KERNEL_SRC ?= /lib/modules/$(KVERSION)
module_out_put_dir := $(PWD)/build
export module_out_put_dir
ragile_common-objs := ragile_common_module.o dfd_tlveeprom.o
obj-m += ragile_platform.o
obj-m += i2c-mux-pca9641.o
obj-m += i2c-mux-pca954x.o
obj-m += ragile_common.o
obj-m += rtcpcf85063.o
#obj-m += tpm_tis_core.o
#obj-m += rg_spi_gpio.o
#obj-m += spi-gpio.o
#obj-m += tpm_tis_spi.o
obj-m += optoe.o
obj-m += rg_at24.o
all :
$(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules
@if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi
cp -p $(PWD)/*.ko $(module_out_put_dir)
clean :
rm -rf $(module_out_put_dir)
rm -f ${PWD}/*.o ${PWD}/*.ko ${PWD}/*.mod.c ${PWD}/.*.cmd ${PWD}/.*.o.d
rm -f ${PWD}/Module.markers ${PWD}/Module.symvers ${PWD}/modules.order
rm -rf ${PWD}/.tmp_versions

View File

@ -1,521 +0,0 @@
/*
* Copyright (C) 2003-2014 FreeIPMI Core Team
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/*****************************************************************************\
* Copyright (C) 2007-2014 Lawrence Livermore National Security, LLC.
* Copyright (C) 2007 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Albert Chu <chu11@llnl.gov>
* UCRL-CODE-232183
*
* This file is part of Ipmi-fru, a tool used for retrieving
* motherboard field replaceable unit (FRU) information. For details,
* see http://www.llnl.gov/linux/.
*
* Ipmi-fru 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.
*
* Ipmi-fru 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 Ipmi-fru. If not, see <http://www.gnu.org/licenses/>.
\*****************************************************************************/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include "ragile.h"
#include "dfd_tlveeprom.h"
/* using in is_valid_tlvinfo_header */
static u_int32_t eeprom_size;
/*
* List of TLV codes and names.
*/
static const struct tlv_code_desc tlv_code_list[] = {
{ TLV_CODE_PRODUCT_NAME , "Product Name"},
{ TLV_CODE_PART_NUMBER , "Part Number"},
{ TLV_CODE_SERIAL_NUMBER , "Serial Number"},
{ TLV_CODE_MAC_BASE , "Base MAC Address"},
{ TLV_CODE_MANUF_DATE , "Manufacture Date"},
{ TLV_CODE_DEVICE_VERSION , "Device Version"},
{ TLV_CODE_LABEL_REVISION , "Label Revision"},
{ TLV_CODE_PLATFORM_NAME , "Platform Name"},
{ TLV_CODE_ONIE_VERSION , "ONIE Version"},
{ TLV_CODE_MAC_SIZE , "MAC Addresses"},
{ TLV_CODE_MANUF_NAME , "Manufacturer"},
{ TLV_CODE_MANUF_COUNTRY , "Country Code"},
{ TLV_CODE_VENDOR_NAME , "Vendor Name"},
{ TLV_CODE_DIAG_VERSION , "Diag Version"},
{ TLV_CODE_SERVICE_TAG , "Service Tag"},
{ TLV_CODE_VENDOR_EXT , "Vendor Extension"},
{ TLV_CODE_CRC_32 , "CRC-32"},
};
#if 0
#define OPENBMC_VPD_KEY_INVAIL_VAL 0
static const tlv_code_map_t tlv_code_map[] = {
{ TLV_CODE_PRODUCT_NAME , OPENBMC_VPD_KEY_PRODUCT_NAME},
{ TLV_CODE_PART_NUMBER , OPENBMC_VPD_KEY_PRODUCT_PART_MODEL_NUM},
{ TLV_CODE_SERIAL_NUMBER , OPENBMC_VPD_KEY_PRODUCT_SERIAL_NUM},
{ TLV_CODE_MAC_BASE , OPENBMC_VPD_KEY_INVAIL_VAL},
{ TLV_CODE_MANUF_DATE , OPENBMC_VPD_KEY_BOARD_MFG_DATE},
{ TLV_CODE_DEVICE_VERSION , OPENBMC_VPD_KEY_PRODUCT_VER},
{ TLV_CODE_LABEL_REVISION , OPENBMC_VPD_KEY_PRODUCT_CUSTOM7},
{ TLV_CODE_PLATFORM_NAME , OPENBMC_VPD_KEY_PRODUCT_CUSTOM1},
{ TLV_CODE_ONIE_VERSION , OPENBMC_VPD_KEY_PRODUCT_CUSTOM2},
{ TLV_CODE_MAC_SIZE , OPENBMC_VPD_KEY_INVAIL_VAL},
{ TLV_CODE_MANUF_NAME , OPENBMC_VPD_KEY_PRODUCT_MFR},
{ TLV_CODE_MANUF_COUNTRY , OPENBMC_VPD_KEY_PRODUCT_CUSTOM3},
{ TLV_CODE_VENDOR_NAME , OPENBMC_VPD_KEY_PRODUCT_CUSTOM4},
{ TLV_CODE_DIAG_VERSION , OPENBMC_VPD_KEY_PRODUCT_CUSTOM8},
{ TLV_CODE_SERVICE_TAG , OPENBMC_VPD_KEY_PRODUCT_CUSTOM5},
{ TLV_CODE_VENDOR_EXT , OPENBMC_VPD_KEY_PRODUCT_CUSTOM6},
{ TLV_CODE_CRC_32 , OPENBMC_VPD_KEY_INVAIL_VAL},
};
#endif
#define TLV_CODE_NUM (sizeof(tlv_code_list) / sizeof(tlv_code_list[0]))
#if 0
#define TLV_CODE_MAP_NUM (sizeof(tlv_code_map) / sizeof(tlv_code_map[0]))
#endif
const unsigned long crc_table[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
};
static unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned len)
{
unsigned i;
if (len < 1)
return 0xffffffff;
for (i = 0; i != len; ++i)
{
crc = crc_table[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
}
crc = crc ^ 0xffffffff;
return crc;
}
/*
* is_valid_tlv
*
* Perform basic sanity checks on a TLV field. The TLV is pointed to
* by the parameter provided.
* 1. The type code is not reserved (0x00 or 0xFF)
*/
static inline bool is_valid_tlv(tlvinfo_tlv_t *tlv)
{
return ((tlv->type != 0x00) && (tlv->type != 0xFF));
}
/*
* is_valid_tlvinfo_header
*
* Perform sanity checks on the first 11 bytes of the TlvInfo EEPROM
* data pointed to by the parameter:
* 1. First 8 bytes contain null-terminated ASCII string "TlvInfo"
* 2. Version byte is 1
* 3. Total length bytes contain value which is less than or equal
* to the allowed maximum (2048-11)
*
*/
static inline bool is_valid_tlvinfo_header(tlvinfo_header_t *hdr)
{
int max_size = eeprom_size;
return((strcmp(hdr->signature, TLV_INFO_ID_STRING) == 0) &&
(hdr->version == TLV_INFO_VERSION) &&
(be16_to_cpu(hdr->totallen) <= max_size) );
}
/*
* decode_tlv_value
*
* Decode a single TLV value into a string.
* The validity of EEPROM contents and the TLV field have been verified
* prior to calling this function.
*/
static void decode_tlv_value(tlvinfo_tlv_t *tlv, tlv_decode_value_t *decode_value)
{
int i;
char *value;
u_int32_t length;
value = (char *)decode_value->value;
switch (tlv->type) {
case TLV_CODE_PRODUCT_NAME:
case TLV_CODE_PART_NUMBER:
case TLV_CODE_SERIAL_NUMBER:
case TLV_CODE_MANUF_DATE:
case TLV_CODE_LABEL_REVISION:
case TLV_CODE_PLATFORM_NAME:
case TLV_CODE_ONIE_VERSION:
case TLV_CODE_MANUF_NAME:
case TLV_CODE_MANUF_COUNTRY:
case TLV_CODE_VENDOR_NAME:
case TLV_CODE_DIAG_VERSION:
case TLV_CODE_SERVICE_TAG:
case TLV_CODE_VENDOR_EXT:
memcpy(value, tlv->value, tlv->length);
value[tlv->length] = 0;
length = tlv->length;
break;
case TLV_CODE_MAC_BASE:
length = sprintf(value, "%02X:%02X:%02X:%02X:%02X:%02X",
tlv->value[0], tlv->value[1], tlv->value[2],
tlv->value[3], tlv->value[4], tlv->value[5]);
break;
case TLV_CODE_DEVICE_VERSION:
length = sprintf(value, "%u", tlv->value[0]);
break;
case TLV_CODE_MAC_SIZE:
length = sprintf(value, "%u", (tlv->value[0] << 8) | tlv->value[1]);
break;
#if 0
case TLV_CODE_VENDOR_EXT:
value[0] = 0;
length = 0;
for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length); i++) {
length += sprintf(value, "%s 0x%02X", value, tlv->value[i]);
}
break;
#endif
case TLV_CODE_CRC_32:
length = sprintf(value, "0x%02X%02X%02X%02X", tlv->value[0],
tlv->value[1], tlv->value[2], tlv->value[3]);
break;
default:
value[0] = 0;
length = 0;
for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length); i++) {
length += sprintf(value, "%s 0x%02X", value, tlv->value[i]);
}
break;
}
decode_value->length = length;
}
/*
* is_checksum_valid
*
* Validate the checksum in the provided TlvInfo EEPROM data. First,
* verify that the TlvInfo header is valid, then make sure the last
* TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data
* and compare it to the value stored in the EEPROM CRC-32 TLV.
*/
static bool is_checksum_valid(u_int8_t *eeprom)
{
tlvinfo_header_t *eeprom_hdr;
tlvinfo_tlv_t *eeprom_crc;
unsigned int calc_crc;
unsigned int stored_crc;
eeprom_hdr = (tlvinfo_header_t *) eeprom;
/* Is the eeprom header valid? */
if (!is_valid_tlvinfo_header(eeprom_hdr)) {
return false;
}
/* Is the last TLV a CRC? */
eeprom_crc = (tlvinfo_tlv_t *) &eeprom[sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen) - (sizeof(tlvinfo_tlv_t) + 4)];
if ((eeprom_crc->type != TLV_CODE_CRC_32) || (eeprom_crc->length != 4)) {
return false;
}
/* Calculate the checksum */
calc_crc = crc32(0xffffffffL, (const unsigned char *)eeprom, sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen) - 4);
stored_crc = ((eeprom_crc->value[0] << 24) | (eeprom_crc->value[1] << 16) |
(eeprom_crc->value[2] << 8) | eeprom_crc->value[3]);
return (calc_crc == stored_crc);
}
/*
* tlvinfo_find_tlv
*
* This function finds the TLV with the supplied code in the EERPOM.
* An offset from the beginning of the EEPROM is returned in the
* eeprom_index parameter if the TLV is found.
*/
static bool tlvinfo_find_tlv(u_int8_t *eeprom, u_int8_t tcode, int *eeprom_index)
{
tlvinfo_header_t *eeprom_hdr;
tlvinfo_tlv_t *eeprom_tlv;
int eeprom_end;
eeprom_hdr = (tlvinfo_header_t *) eeprom;
/* Search through the TLVs, looking for the first one which matches the
supplied type code. */
*eeprom_index = sizeof(tlvinfo_header_t);
eeprom_end = sizeof(tlvinfo_header_t) + be16_to_cpu(eeprom_hdr->totallen);
while (*eeprom_index < eeprom_end) {
eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[*eeprom_index];
if (!is_valid_tlv(eeprom_tlv)) {
return false;
}
if (eeprom_tlv->type == tcode) {
return true;
}
*eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length;
}
return false;
}
/*
* tlvinfo_decode_tlv
*
* This function finds the TLV with the supplied code in the EERPOM
* and decodes the value into the buffer provided.
*/
static bool tlvinfo_decode_tlv(u_int8_t *eeprom, u_int8_t tcode, tlv_decode_value_t *decode_value)
{
int eeprom_index;
tlvinfo_tlv_t *eeprom_tlv;
/* Find the TLV and then decode it */
if (tlvinfo_find_tlv(eeprom, tcode, &eeprom_index)) {
eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[eeprom_index];
decode_tlv_value(eeprom_tlv, decode_value);
return true;
}
return false;
}
/*
* parse_tlv_eeprom
*
* parse the EEPROM into memory, if it hasn't already been read.
*/
int parse_tlv_eeprom(u_int8_t *eeprom, u_int32_t size)
{
unsigned int i;
bool ret;
tlvinfo_header_t *eeprom_hdr;
//tlv_info_vec_t tlv_info;
tlv_decode_value_t decode_value;
int j;
eeprom_hdr = (tlvinfo_header_t *) eeprom;
eeprom_size = size; /* eeprom real size */
if (!is_valid_tlvinfo_header(eeprom_hdr)) {
DBG_ERROR("Failed to check tlv header.\n");
return -1;
}
if (!is_checksum_valid(eeprom)) {
DBG_ERROR("Failed to check tlv crc.\n");
return -1;
}
for (i = 0; i < TLV_CODE_NUM; i++) {
mem_clear((void *)&decode_value, sizeof(tlv_decode_value_t));
ret = tlvinfo_decode_tlv(eeprom, tlv_code_list[i].m_code, &decode_value);
if (!ret) {
DBG_ERROR("No found type: %s\n", tlv_code_list[i].m_name);
continue;
}
DBG_DEBUG("i: %d,Found type: %s tlv[%d]:%s\n", i, tlv_code_list[i].m_name, tlv_code_list[i].m_code,
decode_value.value);
for (j = 0; j < decode_value.length; j++) {
if ((j % 16) == 0) {
DBG_DEBUG("\n");
}
DBG_DEBUG("%02x ", decode_value.value[j]);
}
DBG_DEBUG("\n\n");
}
return 0;
}
static int dfd_parse_tlv_eeprom(u_int8_t *eeprom, u_int32_t size, u_int8_t main_type, tlv_decode_value_t *decode_value)
{
bool ret;
tlvinfo_header_t *eeprom_hdr;
/* tlv_info_vec_t tlv_info; */
int j;
eeprom_hdr = (tlvinfo_header_t *) eeprom;
eeprom_size = size; /* eeprom real size */
if (!is_valid_tlvinfo_header(eeprom_hdr)) {
DBG_ERROR("Failed to check tlv header.\n");
return -1;
}
if (!is_checksum_valid(eeprom)) {
DBG_ERROR("Failed to check tlv crc.\n");
return -1;
}
ret = tlvinfo_decode_tlv(eeprom, main_type, decode_value);
if (!ret) {
DBG_ERROR("No found type: %d\n", main_type);
return -1;
}
DBG_DEBUG("Found type: %d, value: %s\n", main_type,decode_value->value);
for (j = 0; j < decode_value->length; j++) {
if ((j % 16) == 0) {
DBG_DEBUG("\n");
}
DBG_DEBUG("%02x ", decode_value->value[j]);
}
DBG_DEBUG("\n\n");
return 0;
}
/* analyze the extended custom TLV format */
static int tlvinfo_find_rg_ext_tlv(tlv_decode_value_t *ext_tlv_value, u_int8_t ext_type,
u_int8_t *buf, u_int8_t *buf_len)
{
tlvinfo_tlv_t *eeprom_tlv;
int eeprom_end, eeprom_index;
/* Search through the TLVs, looking for the first one which matches the
supplied type code. */
DBG_DEBUG("ext_tlv_value->length: %d.\n", ext_tlv_value->length);
for (eeprom_index = 0; eeprom_index < ext_tlv_value->length; eeprom_index++) {
if ((eeprom_index % 16) == 0) {
DBG_DEBUG("\n");
}
DBG_DEBUG("%02x ", ext_tlv_value->value[eeprom_index]);
}
DBG_DEBUG("\n");
eeprom_index = 0;
eeprom_end = ext_tlv_value->length;
while (eeprom_index < eeprom_end) {
eeprom_tlv = (tlvinfo_tlv_t *) &(ext_tlv_value->value[eeprom_index]);
if (!is_valid_tlv(eeprom_tlv)) {
DBG_ERROR("tlv is not valid, eeprom_tlv->type 0x%x.\n", eeprom_tlv->type);
return -1;
}
DBG_DEBUG("eeprom_tlv->length %d.\n", eeprom_tlv->length);
if (eeprom_tlv->type == ext_type) {
if (*buf_len >= eeprom_tlv->length) {
memcpy(buf, eeprom_tlv->value, eeprom_tlv->length);
DBG_DEBUG("eeprom_tlv->length %d.\n", eeprom_tlv->length);
*buf_len = eeprom_tlv->length;
return 0;
}
DBG_ERROR("buf_len %d small than info_len %d.\n", *buf_len, eeprom_tlv->length);
return -1;
}
eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length;
}
DBG_ERROR("ext_type %d: tlv is not found.\n", ext_type);
return -1;
}
/* get EEPROM information */
int dfd_tlvinfo_get_e2prom_info(u_int8_t *eeprom, u_int32_t size, dfd_tlv_type_t *tlv_type, u_int8_t* buf, u_int8_t *buf_len)
{
tlv_decode_value_t decode_value;
int ret;
if (eeprom == NULL || tlv_type == NULL || buf == NULL) {
DBG_ERROR("Input para invalid.\n");
return -1;
}
mem_clear((void *)&decode_value, sizeof(tlv_decode_value_t));
ret = dfd_parse_tlv_eeprom(eeprom, size, tlv_type->main_type, &decode_value);
if (ret) {
DBG_ERROR("dfd_parse_tlv_eeprom failed ret %d.\n", ret);
return ret;
}
/* For non-extended types, return data directly */
if (tlv_type->main_type != TLV_CODE_VENDOR_EXT) {
if (*buf_len >= decode_value.length) {
memcpy(buf, decode_value.value, decode_value.length);
*buf_len = decode_value.length;
return 0;
}
DBG_ERROR("buf_len %d small than info_len %d.\n", *buf_len, decode_value.length);
return -1;
}
DBG_DEBUG("info_len %d.\n", decode_value.length);
/* For the extended type, continue with the secondary TLV analysis to obtain
the data corresponding to the sub-TLV type */
return tlvinfo_find_rg_ext_tlv(&decode_value, tlv_type->ext_type, buf, buf_len);
}

View File

@ -1,121 +0,0 @@
#ifndef DFD_OPENBMC_TLVEEPROM_H
#define DFD_OPENBMC_TLVEEPROM_H
#ifndef u_int8_t
#define u_int8_t unsigned char
#endif
#ifndef u_int16_t
#define u_int16_t unsigned short
#endif
#ifndef u_int32_t
#define u_int32_t unsigned int
#endif
#ifndef be16_to_cpu
#define be16_to_cpu(x) ntohs(x)
#endif
#ifndef cpu_to_be16
#define cpu_to_be16(x) htons(x)
#endif
/**
* The TLV Types.
*
* Keep these in sync with tlv_code_list in cmd_sys_eeprom.c
*/
#define TLV_CODE_PRODUCT_NAME 0x21
#define TLV_CODE_PART_NUMBER 0x22
#define TLV_CODE_SERIAL_NUMBER 0x23
#define TLV_CODE_MAC_BASE 0x24
#define TLV_CODE_MANUF_DATE 0x25
#define TLV_CODE_DEVICE_VERSION 0x26
#define TLV_CODE_LABEL_REVISION 0x27
#define TLV_CODE_PLATFORM_NAME 0x28
#define TLV_CODE_ONIE_VERSION 0x29
#define TLV_CODE_MAC_SIZE 0x2A
#define TLV_CODE_MANUF_NAME 0x2B
#define TLV_CODE_MANUF_COUNTRY 0x2C
#define TLV_CODE_VENDOR_NAME 0x2D
#define TLV_CODE_DIAG_VERSION 0x2E
#define TLV_CODE_SERVICE_TAG 0x2F
#define TLV_CODE_VENDOR_EXT 0xFD
#define TLV_CODE_CRC_32 0xFE
#define TLV_CODE_NAME_LEN 64
/*
* Struct for displaying the TLV codes and names.
*/
struct tlv_code_desc {
u_int8_t m_code;
char m_name[TLV_CODE_NAME_LEN];
};
/* ONIE TLV Type and Extended TLV Type Definition */
typedef struct dfd_tlv_type_s {
u_int8_t main_type;/* ONIE standard TLV TYPE type */
u_int8_t ext_type; /* Extended TLV TYPE type */
} dfd_tlv_type_t;
/* Header Field Constants */
#define TLV_INFO_ID_STRING "TlvInfo"
#define TLV_INFO_VERSION 0x01
/*#define TLV_TOTAL_LEN_MAX (XXXXXXXX - sizeof(tlvinfo_header_t))*/
struct __attribute__ ((__packed__)) tlvinfo_header_s {
char signature[8]; /* 0x00 - 0x07 EEPROM Tag "TlvInfo" */
u_int8_t version; /* 0x08 Structure version */
u_int16_t totallen; /* 0x09 - 0x0A Length of all data which follows */
};
typedef struct tlvinfo_header_s tlvinfo_header_t;
/*
* TlvInfo TLV: Layout of a TLV field
*/
struct __attribute__ ((__packed__)) tlvinfo_tlv_s {
u_int8_t type;
u_int8_t length;
u_int8_t value[0];
};
typedef struct tlvinfo_tlv_s tlvinfo_tlv_t;
#define TLV_VALUE_MAX_LEN 255
/*
* The max decode value is currently for the 'raw' type or the 'vendor
* extension' type, both of which have the same decode format. The
* max decode string size is computed as follows:
*
* strlen(" 0xFF") * TLV_VALUE_MAX_LEN + 1
*
*/
#define TLV_DECODE_VALUE_MAX_LEN ((5 * TLV_VALUE_MAX_LEN) + 1)
typedef struct tlv_decode_value_s {
u_int8_t value[TLV_DECODE_VALUE_MAX_LEN];
u_int32_t length;
} tlv_decode_value_t;
typedef enum dfd_tlvinfo_ext_tlv_type_e {
DFD_TLVINFO_EXT_TLV_TYPE_DEV_TYPE = 1,
} dfd_tlvinfo_ext_tlv_type_t;
#if 0
#define TLV_TIME_LEN 64
int ipmi_tlv_validate_fru_area(const uint8_t fruid, const char *fru_file_name,
sd_bus *bus_type, const bool bmc_fru);
extern const char *get_vpd_key_names(int key_id);
extern std::string getService(sdbusplus::bus::bus& bus,
const std::string& intf,
const std::string& path);
extern std::string getFRUValue(const std::string& section,
const std::string& key,
const std::string& delimiter,
IPMIFruInfo& fruData);
#endif
int dfd_tlvinfo_get_e2prom_info(u_int8_t *eeprom, u_int32_t size, dfd_tlv_type_t *tlv_type, u_int8_t* buf, u_int8_t *buf_len);
#endif /* endif DFD_OPENBMC_TLVEEPROM_H */

View File

@ -1,643 +0,0 @@
/*
* I2C multiplexer driver for PCA9541 bus master selector
*
* Copyright (c) 2010 Ericsson AB.
*
* Author: Guenter Roeck <linux@roeck-us.net>
*
* Derived from:
* pca954x.c
*
* Copyright (c) 2008-2009 Rodolfo Giometti <giometti@linux.it>
* Copyright (c) 2008-2009 Eurotech S.p.A. <info@eurotech.it>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/bitops.h>
/*
* The PCA9541 is a bus master selector. It supports two I2C masters connected
* to a single slave bus.
*
* Before each bus transaction, a master has to acquire bus ownership. After the
* transaction is complete, bus ownership has to be released. This fits well
* into the I2C multiplexer framework, which provides select and release
* functions for this purpose. For this reason, this driver is modeled as
* single-channel I2C bus multiplexer.
*
* This driver assumes that the two bus masters are controlled by two different
* hosts. If a single host controls both masters, platform code has to ensure
* that only one of the masters is instantiated at any given time.
*/
#define PCA9541_CONTROL 0x01
#define PCA9541_ISTAT 0x02
#define PCA9541_CTL_MYBUS (1 << 0)
#define PCA9541_CTL_NMYBUS (1 << 1)
#define PCA9541_CTL_BUSON (1 << 2)
#define PCA9541_CTL_NBUSON (1 << 3)
#define PCA9541_CTL_BUSINIT (1 << 4)
#define PCA9541_CTL_TESTON (1 << 6)
#define PCA9541_CTL_NTESTON (1 << 7)
#define PCA9541_ISTAT_INTIN (1 << 0)
#define PCA9541_ISTAT_BUSINIT (1 << 1)
#define PCA9541_ISTAT_BUSOK (1 << 2)
#define PCA9541_ISTAT_BUSLOST (1 << 3)
#define PCA9541_ISTAT_MYTEST (1 << 6)
#define PCA9541_ISTAT_NMYTEST (1 << 7)
#define PCA9641_ID 0x00
#define PCA9641_ID_MAGIC 0x38
#define PCA9641_CONTROL 0x01
#define PCA9641_STATUS 0x02
#define PCA9641_TIME 0x03
#define PCA9641_CTL_LOCK_REQ BIT(0)
#define PCA9641_CTL_LOCK_GRANT BIT(1)
#define PCA9641_CTL_BUS_CONNECT BIT(2)
#define PCA9641_CTL_BUS_INIT BIT(3)
#define PCA9641_CTL_SMBUS_SWRST BIT(4)
#define PCA9641_CTL_IDLE_TIMER_DIS BIT(5)
#define PCA9641_CTL_SMBUS_DIS BIT(6)
#define PCA9641_CTL_PRIORITY BIT(7)
#define PCA9641_STS_OTHER_LOCK BIT(0)
#define PCA9641_STS_BUS_INIT_FAIL BIT(1)
#define PCA9641_STS_BUS_HUNG BIT(2)
#define PCA9641_STS_MBOX_EMPTY BIT(3)
#define PCA9641_STS_MBOX_FULL BIT(4)
#define PCA9641_STS_TEST_INT BIT(5)
#define PCA9641_STS_SCL_IO BIT(6)
#define PCA9641_STS_SDA_IO BIT(7)
#define PCA9641_RES_TIME 0x03
#define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON)
#define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS)
#define mybus(x) (!((x) & MYBUS) || ((x) & MYBUS) == MYBUS)
#define busoff(x) (!((x) & BUSON) || ((x) & BUSON) == BUSON)
#define BUSOFF(x, y) (!((x) & PCA9641_CTL_LOCK_GRANT) && \
!((y) & PCA9641_STS_OTHER_LOCK))
#define other_lock(x) ((x) & PCA9641_STS_OTHER_LOCK)
#define lock_grant(x) ((x) & PCA9641_CTL_LOCK_GRANT)
#define PCA9641_RETRY_TIME 8
typedef struct i2c_muxs_struct_flag
{
int nr;
char name[48];
struct mutex update_lock;
int flag;
}i2c_mux_flag;
i2c_mux_flag pca_flag = {
.flag = -1,
};
int pca9641_setmuxflag(int nr, int flag)
{
if (pca_flag.nr == nr) {
pca_flag.flag = flag;
}
return 0;
}
EXPORT_SYMBOL(pca9641_setmuxflag);
int g_debug = 0;
module_param(g_debug, int, S_IRUGO | S_IWUSR);
#define PCA_DEBUG(fmt, args...) do { \
if (g_debug) { \
printk(KERN_ERR "[pca9641][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
/* arbitration timeouts, in jiffies */
#define ARB_TIMEOUT (HZ / 8) /* 125 ms until forcing bus ownership */
#define ARB2_TIMEOUT (HZ / 4) /* 250 ms until acquisition failure */
/* arbitration retry delays, in us */
#define SELECT_DELAY_SHORT 50
#define SELECT_DELAY_LONG 1000
struct pca9541 {
struct i2c_client *client;
unsigned long select_timeout;
unsigned long arb_timeout;
};
static const struct i2c_device_id pca9541_id[] = {
{"pca9541", 0},
{"pca9641", 1},
{}
};
MODULE_DEVICE_TABLE(i2c, pca9541_id);
#ifdef CONFIG_OF
static const struct of_device_id pca9541_of_match[] = {
{ .compatible = "nxp,pca9541" },
{ .compatible = "nxp,pca9641" },
{}
};
MODULE_DEVICE_TABLE(of, pca9541_of_match);
#endif
/*
* Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer()
* as they will try to lock the adapter a second time.
*/
static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val)
{
struct i2c_adapter *adap = client->adapter;
int ret;
if (adap->algo->master_xfer) {
struct i2c_msg msg;
char buf[2];
msg.addr = client->addr;
msg.flags = 0;
msg.len = 2;
buf[0] = command;
buf[1] = val;
msg.buf = buf;
ret = __i2c_transfer(adap, &msg, 1);
} else {
union i2c_smbus_data data;
data.byte = val;
ret = adap->algo->smbus_xfer(adap, client->addr,
client->flags,
I2C_SMBUS_WRITE,
command,
I2C_SMBUS_BYTE_DATA, &data);
}
return ret;
}
/*
* Read from chip register. Don't use i2c_transfer()/i2c_smbus_xfer()
* as they will try to lock adapter a second time.
*/
static int pca9541_reg_read(struct i2c_client *client, u8 command)
{
struct i2c_adapter *adap = client->adapter;
int ret;
u8 val;
if (adap->algo->master_xfer) {
struct i2c_msg msg[2] = {
{
.addr = client->addr,
.flags = 0,
.len = 1,
.buf = &command
},
{
.addr = client->addr,
.flags = I2C_M_RD,
.len = 1,
.buf = &val
}
};
ret = __i2c_transfer(adap, msg, 2);
if (ret == 2)
ret = val;
else if (ret >= 0)
ret = -EIO;
} else {
union i2c_smbus_data data;
ret = adap->algo->smbus_xfer(adap, client->addr,
client->flags,
I2C_SMBUS_READ,
command,
I2C_SMBUS_BYTE_DATA, &data);
if (!ret)
ret = data.byte;
}
return ret;
}
/*
* Arbitration management functions
*/
/* Release bus. Also reset NTESTON and BUSINIT if it was set. */
static void pca9541_release_bus(struct i2c_client *client)
{
int reg;
reg = pca9541_reg_read(client, PCA9541_CONTROL);
if (reg >= 0 && !busoff(reg) && mybus(reg))
pca9541_reg_write(client, PCA9541_CONTROL,
(reg & PCA9541_CTL_NBUSON) >> 1);
}
/*
* Arbitration is defined as a two-step process. A bus master can only activate
* the slave bus if it owns it; otherwise it has to request ownership first.
* This multi-step process ensures that access contention is resolved
* gracefully.
*
* Bus Ownership Other master Action
* state requested access
* ----------------------------------------------------
* off - yes wait for arbitration timeout or
* for other master to drop request
* off no no take ownership
* off yes no turn on bus
* on yes - done
* on no - wait for arbitration timeout or
* for other master to release bus
*
* The main contention point occurs if the slave bus is off and both masters
* request ownership at the same time. In this case, one master will turn on
* the slave bus, believing that it owns it. The other master will request
* bus ownership. Result is that the bus is turned on, and master which did
* _not_ own the slave bus before ends up owning it.
*/
/* Control commands per PCA9541 datasheet */
static const u8 pca9541_control[16] = {
4, 0, 1, 5, 4, 4, 5, 5, 0, 0, 1, 1, 0, 4, 5, 1
};
/*
* Channel arbitration
*
* Return values:
* <0: error
* 0 : bus not acquired
* 1 : bus acquired
*/
static int pca9541_arbitrate(struct i2c_client *client)
{
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
struct pca9541 *data = i2c_mux_priv(muxc);
int reg;
reg = pca9541_reg_read(client, PCA9541_CONTROL);
if (reg < 0)
return reg;
if (busoff(reg)) {
int istat;
/*
* Bus is off. Request ownership or turn it on unless
* other master requested ownership.
*/
istat = pca9541_reg_read(client, PCA9541_ISTAT);
if (!(istat & PCA9541_ISTAT_NMYTEST)
|| time_is_before_eq_jiffies(data->arb_timeout)) {
/*
* Other master did not request ownership,
* or arbitration timeout expired. Take the bus.
*/
pca9541_reg_write(client,
PCA9541_CONTROL,
pca9541_control[reg & 0x0f]
| PCA9541_CTL_NTESTON);
data->select_timeout = SELECT_DELAY_SHORT;
} else {
/*
* Other master requested ownership.
* Set extra long timeout to give it time to acquire it.
*/
data->select_timeout = SELECT_DELAY_LONG * 2;
}
} else if (mybus(reg)) {
/*
* Bus is on, and we own it. We are done with acquisition.
* Reset NTESTON and BUSINIT, then return success.
*/
if (reg & (PCA9541_CTL_NTESTON | PCA9541_CTL_BUSINIT))
pca9541_reg_write(client,
PCA9541_CONTROL,
reg & ~(PCA9541_CTL_NTESTON
| PCA9541_CTL_BUSINIT));
return 1;
} else {
/*
* Other master owns the bus.
* If arbitration timeout has expired, force ownership.
* Otherwise request it.
*/
data->select_timeout = SELECT_DELAY_LONG;
if (time_is_before_eq_jiffies(data->arb_timeout)) {
/* Time is up, take the bus and reset it. */
pca9541_reg_write(client,
PCA9541_CONTROL,
pca9541_control[reg & 0x0f]
| PCA9541_CTL_BUSINIT
| PCA9541_CTL_NTESTON);
} else {
/* Request bus ownership if needed */
if (!(reg & PCA9541_CTL_NTESTON))
pca9541_reg_write(client,
PCA9541_CONTROL,
reg | PCA9541_CTL_NTESTON);
}
}
return 0;
}
static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan)
{
struct pca9541 *data = i2c_mux_priv(muxc);
struct i2c_client *client = data->client;
int ret;
unsigned long timeout = jiffies + ARB2_TIMEOUT;
/* give up after this time */
data->arb_timeout = jiffies + ARB_TIMEOUT;
/* force bus ownership after this time */
do {
ret = pca9541_arbitrate(client);
if (ret)
return ret < 0 ? ret : 0;
if (data->select_timeout == SELECT_DELAY_SHORT)
udelay(data->select_timeout);
else
msleep(data->select_timeout / 1000);
} while (time_is_after_eq_jiffies(timeout));
return -ETIMEDOUT;
}
static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan)
{
struct pca9541 *data = i2c_mux_priv(muxc);
struct i2c_client *client = data->client;
pca9541_release_bus(client);
return 0;
}
/*
* Arbitration management functions
*/
static void pca9641_release_bus(struct i2c_client *client)
{
pca9541_reg_write(client, PCA9641_CONTROL, 0x80); /* master 0x80 */
}
/*
* Channel arbitration
*
* Return values:
* <0: error
* 0 : bus not acquired
* 1 : bus acquired
*/
static int pca9641_arbitrate(struct i2c_client *client)
{
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
struct pca9541 *data = i2c_mux_priv(muxc);
int reg_ctl, reg_sts;
reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL);
if (reg_ctl < 0)
return reg_ctl;
reg_sts = pca9541_reg_read(client, PCA9641_STATUS);
if (BUSOFF(reg_ctl, reg_sts)) {
/*
* Bus is off. Request ownership or turn it on unless
* other master requested ownership.
*/
reg_ctl |= PCA9641_CTL_LOCK_REQ;
pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL);
if (lock_grant(reg_ctl)) {
/*
* Other master did not request ownership,
* or arbitration timeout expired. Take the bus.
*/
reg_ctl |= PCA9641_CTL_BUS_CONNECT
| PCA9641_CTL_LOCK_REQ;
pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
data->select_timeout = SELECT_DELAY_SHORT;
return 1;
} else {
/*
* Other master requested ownership.
* Set extra long timeout to give it time to acquire it.
*/
data->select_timeout = SELECT_DELAY_LONG * 2;
}
} else if (lock_grant(reg_ctl)) {
/*
* Bus is on, and we own it. We are done with acquisition.
*/
reg_ctl |= PCA9641_CTL_BUS_CONNECT | PCA9641_CTL_LOCK_REQ;
pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
return 1;
} else if (other_lock(reg_sts)) {
/*
* Other master owns the bus.
* If arbitration timeout has expired, force ownership.
* Otherwise request it.
*/
data->select_timeout = SELECT_DELAY_LONG;
reg_ctl |= PCA9641_CTL_LOCK_REQ;
pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
}
return 0;
}
int pca9641_select_chan(struct i2c_mux_core *muxc, u32 chan)
{
struct pca9541 *data = i2c_mux_priv(muxc);
struct i2c_client *client = data->client;
int ret;
int result;
unsigned long timeout = jiffies + ARB2_TIMEOUT;
/* give up after this time */
data->arb_timeout = jiffies + ARB_TIMEOUT;
/* force bus ownership after this time */
for (result = 0 ; result < PCA9641_RETRY_TIME ; result ++) {
do {
ret = pca9641_arbitrate(client);
if (ret == 1) {
return 0;
}
if (data->select_timeout == SELECT_DELAY_SHORT)
udelay(data->select_timeout);
else
msleep(data->select_timeout / 1000);
} while (time_is_after_eq_jiffies(timeout));
timeout = jiffies + ARB2_TIMEOUT;
}
return -ETIMEDOUT;
}
EXPORT_SYMBOL(pca9641_select_chan);
static int pca9641_release_chan(struct i2c_mux_core *muxc, u32 chan)
{
struct pca9541 *data = i2c_mux_priv(muxc);
struct i2c_client *client = data->client;
if (pca_flag.flag) {
pca9641_release_bus(client);
}
return 0;
}
static int pca9641_detect_id(struct i2c_client *client)
{
int reg;
reg = pca9541_reg_read(client, PCA9641_ID);
if (reg == PCA9641_ID_MAGIC)
return 1;
else
return 0;
}
/**
** Limited: 20180827 supports one PCA9641
**/
static int pca9641_recordflag(struct i2c_adapter *adap) {
if (pca_flag.flag != -1) {
pr_err(" %s %d has init already!!!", __func__, __LINE__);
return -1 ;
}
pca_flag.nr = adap->nr;
PCA_DEBUG(" adap->nr:%d\n", adap->nr);
snprintf(pca_flag.name, sizeof(pca_flag.name),adap->name);
return 0;
}
static void i2c_lock_adapter(struct i2c_adapter *adapter){
struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
if (parent)
i2c_lock_adapter(parent);
else
rt_mutex_lock(&adapter->bus_lock);
}
void i2c_unlock_adapter(struct i2c_adapter *adapter)
{
struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
if (parent)
i2c_unlock_adapter(parent);
else
rt_mutex_unlock(&adapter->bus_lock);
}
/*
* I2C init/probing/exit functions
*/
static int pca9541_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adap = client->adapter;
struct i2c_mux_core *muxc;
struct pca9541 *data;
int force;
int ret = -ENODEV;
int detect_id;
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
detect_id = pca9641_detect_id(client);
/*
* I2C accesses are unprotected here.
* We have to lock the adapter before releasing the bus.
*/
#if 0
i2c_lock_adapter(adap);
pca9541_release_bus(client);
i2c_unlock_adapter(adap);
#endif
if (detect_id == 0) {
i2c_lock_adapter(adap);
pca9541_release_bus(client);
i2c_unlock_adapter(adap);
} else {
i2c_lock_adapter(adap);
pca9641_release_bus(client);
i2c_unlock_adapter(adap);
}
/* Create mux adapter */
if (detect_id == 0) {
muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data),
I2C_MUX_ARBITRATOR,
pca9541_select_chan, pca9541_release_chan);
if (!muxc)
return -ENOMEM;
data = i2c_mux_priv(muxc);
data->client = client;
i2c_set_clientdata(client, muxc);
ret = i2c_mux_add_adapter(muxc, 0, 0, 0);
if (ret)
return ret;
} else {
muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data),
I2C_MUX_ARBITRATOR,
pca9641_select_chan, pca9641_release_chan);
if (!muxc)
return -ENOMEM;
data = i2c_mux_priv(muxc);
data->client = client;
i2c_set_clientdata(client, muxc);
ret = i2c_mux_add_adapter(muxc, force, 0, 0);
if (ret)
return ret;
}
pca9641_recordflag(muxc->adapter[0]);
dev_info(&client->dev, "registered master selector for I2C %s\n",
client->name);
return 0;
}
static int pca9541_remove(struct i2c_client *client)
{
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
i2c_mux_del_adapters(muxc);
return 0;
}
static struct i2c_driver pca9641_driver = {
.driver = {
.name = "pca9641",
.of_match_table = of_match_ptr(pca9541_of_match),
},
.probe = pca9541_probe,
.remove = pca9541_remove,
.id_table = pca9541_id,
};
module_i2c_driver(pca9641_driver);
MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
MODULE_DESCRIPTION("PCA9541 I2C master selector driver");
MODULE_LICENSE("GPL v2");

View File

@ -1,158 +0,0 @@
#ifndef __RAGILE_H__
#define __RAGILE_H__
#include<linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/string.h>
#define mem_clear(data, size) memset((data), 0, (size))
/* debug switch level */
typedef enum {
DBG_START,
DBG_VERBOSE,
DBG_KEY,
DBG_WARN,
DBG_ERROR,
DBG_END,
} dbg_level_t;
typedef enum dfd_cpld_id {
BCM_CPLD0 = 0,
BCM_CPLD1,
CPLD0_MAC0,
CPLD0_MAC1,
CPLD1_MAC0,
CPLD2_MAC1,
} dfd_cpld_id_t;
typedef enum dfd_cpld_bus {
SMBUS_BUS = 0 ,
GPIO_BUS = 1,
PCA9641_BUS = 2,
} dfd_cpld_bus_t;
typedef struct dfd_i2c_dev_s {
int bus; /* bus number */
int addr; /* bus address */
} dfd_i2c_dev_t;
typedef enum dfd_cpld_addr {
CPLD_ADDR_MIN = 0x31,
BCM_CPLD0_ADDR = 0x32, /* pca9641 up */
CPLD0_MAC0_ADDR = 0x33, /* SMBUS down */
CPLD0_MAC1_ADDR = 0x34,
CPLD1_MAC0_ADDR = 0x35,
CPLD2_MAC1_ADDR = 0x36,
BCM_CPLD1_ADDR = 0x37,
CPLD_ADDR_MAX,
} dfd_cpld_addr_t;
typedef struct dfd_dev_head_info_s {
uint8_t ver; /* The version number defined by the E2PROM file, the initial version is 0x01 */
uint8_t flag; /* The new version of E2PROM is identified as 0x7E */
uint8_t hw_ver; /* It consists of two parts: the main version number and the revised version */
uint8_t type; /* Hardware type definition information */
int16_t tlv_len; /* Effective data length (16 bits) */
} dfd_dev_head_info_t;
typedef enum dfd_intf_e{
DFD_INTF_GET_FAN_HW_VERSION,
DFD_INTF_GET_FAN_STATUS,
DFD_INTF_GET_FAN_SPEED_LEVEL,
DFD_INTF_GET_FAN_SPEED,
DFD_INTF_GET_FAN_ATTRIBUTE,
DFD_INTF_GET_FAN_SN,
DFD_INTF_GET_FAN_TYPE,
DFD_INTF_SET_FAN_SPEED_LEVEL,
DFD_INTF_GET_FAN_SUB_NUM,
DFD_INTF_GET_FAN_FAIL_BITMAP,
}dfd_intf_t;
typedef struct dfd_dev_tlv_info_s {
uint8_t type; /* the type of data */
uint8_t len; /* the length of data */
uint8_t data[0]; /* data */
} dfd_dev_tlv_info_t;
typedef enum dfd_dev_info_type_e {
DFD_DEV_INFO_TYPE_MAC = 1,
DFD_DEV_INFO_TYPE_NAME = 2,
DFD_DEV_INFO_TYPE_SN = 3,
DFD_DEV_INFO_TYPE_PWR_CONS = 4,
DFD_DEV_INFO_TYPE_HW_INFO = 5,
DFD_DEV_INFO_TYPE_DEV_TYPE = 6,
} dfd_dev_tlv_type_t;
struct sfp_drivers_t{
/* addr = sff present bitmap addr, index from 0 */
void (*get_number) (unsigned int *number);
int (*get_port_start) (void);
int (*get_port_end) (void);
bool (*is_qsfp_port) (const unsigned int port_num);
bool (*get_present) (unsigned long *bitmap);
bool (*read_sfp_eeprom) (const unsigned int port,
const unsigned char addr,
const unsigned char offset,
const uint32_t count, char *buf);
bool (*write_sfp_eeprom) (const unsigned int port,
const unsigned char addr,
const unsigned char offset,
const unsigned char count,
const char *buf);
bool (*read_sysfs) (const unsigned int bus,
const unsigned char addr,
const unsigned char offset,
const uint32_t count, char *buf);
bool (*write_sysfs) (const unsigned int bus,
const unsigned char addr,
const unsigned char offset,
const unsigned char count,
const char *buf);
bool (*read_block_sysfs) (const unsigned int bus,
const unsigned char addr,
const unsigned char offset,
const uint32_t count, char *buf);
};
extern int debuglevel;
extern int dfd_cpld_read_chipid(int cpldid , uint32_t addr, int32_t size, unsigned char *buf);
extern int dfd_cpld_read(int32_t addr, uint8_t *val);
extern int dfd_cpld_write(int32_t addr, uint8_t val);
extern int rg_i2c_read(uint32_t bus, uint32_t addr, uint32_t offset, uint32_t size, unsigned char *buf) ;
extern int rg_i2c_write(uint32_t bus, uint32_t addr, uint32_t offset, uint8_t buf);
extern int rg_i2c_read_block(uint32_t bus, uint32_t addr, uint32_t offset, uint32_t size, unsigned char *buf) ;
extern int ragile_setdebug(int val);
extern s32 platform_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command);
extern s32 platform_i2c_smbus_read_i2c_block_data(const struct i2c_client *client,
u8 command, u8 length, u8 *values);
extern s32 platform_i2c_smbus_read_word_data(const struct i2c_client *client, u8 command);
extern int sfp_drivers_register(struct sfp_drivers_t *drv);
extern int sfp_drivers_unregister(void);
extern int sysfs_drivers_register(struct sfp_drivers_t *drv);
extern int sysfs_drivers_unregister(void);
#define DBG_DEBUG(fmt, arg...) do { \
if ( debuglevel > DBG_START && debuglevel < DBG_ERROR) { \
printk(KERN_INFO "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \
} else if ( debuglevel >= DBG_ERROR ) { \
printk(KERN_ERR "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \
} else { } \
} while (0)
#define DBG_INFO(fmt, arg...) do { \
if ( debuglevel > DBG_KEY) { \
printk(KERN_INFO "[INFO]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \
} \
} while (0)
#define DBG_ERROR(fmt, arg...) do { \
if ( debuglevel > DBG_START) { \
printk(KERN_ERR "[ERROR]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \
} \
} while (0)
#endif

View File

@ -1,210 +0,0 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/uaccess.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/platform_data/i2c-mux-gpio.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/i2c-smbus.h>
#include <linux/string.h>
#include "ragile.h"
#include "dfd_tlveeprom.h"
#define PLATFORM_I2C_RETRY_TIMES 3
#define DFD_TLVEEPROM_I2C_BUS (0)
#define DFD_TLVEEPROM_I2C_ADDR (0x56)
#define DFD_E2PROM_MAX_LEN (256)
#define DFD_CARDTYPE_EXT_TLVLEN (4)
#define PLATFORM_CARDTYPE_RETRY_CNT (10)
#define PLATFORM_CARDTYPE_RETRY_TIMES (1000)
int debuglevel = 0;
module_param(debuglevel, int, S_IRUGO | S_IWUSR);
static int dfd_my_type = 0;
module_param(dfd_my_type, int, S_IRUGO | S_IWUSR);
int g_common_debug_error = 0;
module_param(g_common_debug_error, int, S_IRUGO | S_IWUSR);
int g_common_debug_verbose = 0;
module_param(g_common_debug_verbose, int, S_IRUGO | S_IWUSR);
uint32_t dfd_my_type_i2c_bus = 0;
module_param(dfd_my_type_i2c_bus, int, S_IRUGO | S_IWUSR);
uint32_t dfd_my_type_i2c_addr = 0;
module_param(dfd_my_type_i2c_addr, int, S_IRUGO | S_IWUSR);
#define RAGILE_COMMON_DEBUG_VERBOSE(fmt, args...) do { \
if (g_common_debug_verbose) { \
printk(KERN_ERR "[RAGILE_COMMON][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
#define RAGILE_COMMON_DEBUG_ERROR(fmt, args...) do { \
if (g_common_debug_error) { \
printk(KERN_ERR "[RAGILE_COMMON][ERROR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
static int32_t dfd_i2c_read(char *dev, uint32_t addr, uint32_t offset_addr, unsigned char *
buf, int32_t size)
{
struct file *fp;
mm_segment_t fs;
struct i2c_client client;
int i ,j ;
int rv;
s32 val_t;
val_t = -1;
rv = 0;
fp = filp_open(dev, O_RDWR, S_IRUSR | S_IWUSR);
if (IS_ERR(fp)) {
DBG_ERROR("i2c open fail.\n");
RAGILE_COMMON_DEBUG_ERROR("i2c open fail.\n");
return -1;
}
memcpy(&client, fp->private_data, sizeof(struct i2c_client));
client.addr = addr;
fs = get_fs();
set_fs(KERNEL_DS);
for (j = 0 ;j < size ;j++){
for (i = 0; i < PLATFORM_I2C_RETRY_TIMES; i++) {
if ((val_t = i2c_smbus_read_byte_data(&client, (offset_addr + j))) < 0) {
DBG_DEBUG("read try(%d)time offset_addr:%x \n", i, offset_addr);
continue;
} else {
* (buf + j) = val_t;
break;
}
}
if (val_t < 0) {
rv = -1;
break;
}
}
filp_close(fp, NULL);
set_fs(fs);
return rv;
}
static int dfd_tlvinfo_get_cardtype(void)
{
char i2c_path[16] = {0};
int ret;
int cardtype;
u_int8_t eeprom[DFD_E2PROM_MAX_LEN];
dfd_i2c_dev_t i2c_dev;
uint8_t buf[DFD_CARDTYPE_EXT_TLVLEN];
uint8_t len;
dfd_tlv_type_t tlv_type;
if (dfd_my_type_i2c_bus != 0) {
i2c_dev.bus = dfd_my_type_i2c_bus;
} else {
i2c_dev.bus = DFD_TLVEEPROM_I2C_BUS;
}
if (dfd_my_type_i2c_addr != 0) {
i2c_dev.addr = dfd_my_type_i2c_addr;
} else {
i2c_dev.addr = DFD_TLVEEPROM_I2C_ADDR;
}
snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", i2c_dev.bus);
RAGILE_COMMON_DEBUG_VERBOSE("Read device eeprom info:(dev:%s, addr:%02x).\n", i2c_path, i2c_dev.addr);
ret = dfd_i2c_read(i2c_path, i2c_dev.addr, 0, eeprom, DFD_E2PROM_MAX_LEN);
if (ret != 0) {
DBG_ERROR("Read eeprom info error(dev: %s, addr: %02x).\n", i2c_path, i2c_dev.addr);
RAGILE_COMMON_DEBUG_ERROR("Read eeprom info error(dev: %s, addr: %02x).\n", i2c_path, i2c_dev.addr);
return ret;
}
tlv_type.main_type = TLV_CODE_VENDOR_EXT;
tlv_type.ext_type = DFD_TLVINFO_EXT_TLV_TYPE_DEV_TYPE;
len = sizeof(buf);
mem_clear(buf, len);
ret = dfd_tlvinfo_get_e2prom_info(eeprom, DFD_E2PROM_MAX_LEN, &tlv_type, buf, &len);
if (ret) {
DBG_ERROR("dfd_tlvinfo_get_e2prom_info failed ret %d.\n", ret);
return -1;
}
for (ret = 0; ret < 4; ret++) {
DBG_DEBUG("buf 0x%02x.\n", buf[ret]);
}
cardtype = ntohl(*((uint32_t *)buf));
DBG_DEBUG("cardtype 0x%x.\n", cardtype);
return cardtype;
}
static int __dfd_get_my_card_type(void)
{
return dfd_tlvinfo_get_cardtype();
}
/* Get its own card type */
int dfd_get_my_card_type(void)
{
int type;
int cnt;
if (dfd_my_type != 0) {
DBG_DEBUG("my_type = 0x%x\r\n", dfd_my_type);
return dfd_my_type;
}
cnt = PLATFORM_CARDTYPE_RETRY_CNT;
while (cnt--) {
type = __dfd_get_my_card_type();
if (type < 0) {
RAGILE_COMMON_DEBUG_ERROR("__dfd_get_my_card_type fail cnt %d, ret %d.\n", cnt, type);
msleep(PLATFORM_CARDTYPE_RETRY_TIMES);
continue;
}
RAGILE_COMMON_DEBUG_VERBOSE("success to get type 0x%x.\n", type);
break;
}
dfd_my_type = type;
return dfd_my_type;
}
EXPORT_SYMBOL(dfd_get_my_card_type);
static int __init ragile_common_init(void)
{
int ret;
RAGILE_COMMON_DEBUG_VERBOSE("Enter.\n");
ret = dfd_get_my_card_type();
if (ret <= 0) {
RAGILE_COMMON_DEBUG_ERROR("dfd_get_my_card_type failed, ret %d.\n", ret);
printk(KERN_ERR "Warning: Device type get failed, please check the TLV-EEPROM!\n");
return -1;
}
RAGILE_COMMON_DEBUG_VERBOSE("Leave success type 0x%x.\n", ret);
return 0;
}
static void __exit ragile_common_exit(void)
{
RAGILE_COMMON_DEBUG_VERBOSE("Exit.\n");
}
module_init(ragile_common_init);
module_exit(ragile_common_exit);
MODULE_DESCRIPTION("ragile Platform Support");
MODULE_AUTHOR("tangjiamiao <support@ragilenetworks.com>");
MODULE_LICENSE("GPL");

View File

@ -1,79 +0,0 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/uaccess.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/platform_data/i2c-gpio.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/i2c-smbus.h>
#include <linux/string.h>
#include "ragile.h"
#define PLATFORM_I2C_RETRY_TIMES 3
s32 platform_i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command)
{
int try;
s32 ret;
ret = -1;
for (try = 0; try < PLATFORM_I2C_RETRY_TIMES; try++) {
if ((ret = i2c_smbus_read_byte_data(client, command)) >= 0 )
break;
}
return ret;
}
EXPORT_SYMBOL(platform_i2c_smbus_read_byte_data);
s32 platform_i2c_smbus_read_i2c_block_data(const struct i2c_client *client,
u8 command, u8 length, u8 *values)
{
int try;
s32 ret;
ret = -1;
for (try = 0; try < PLATFORM_I2C_RETRY_TIMES; try++) {
if ((ret = i2c_smbus_read_i2c_block_data(client, command, length, values)) >= 0 )
break;
}
return ret;
}
EXPORT_SYMBOL(platform_i2c_smbus_read_i2c_block_data);
s32 platform_i2c_smbus_read_word_data(const struct i2c_client *client, u8 command)
{
int try;
s32 ret;
ret = -1;
for (try = 0; try < PLATFORM_I2C_RETRY_TIMES; try++) {
if ((ret = i2c_smbus_read_word_data(client, command)) >= 0 )
break;
}
return ret;
}
EXPORT_SYMBOL(platform_i2c_smbus_read_word_data);
static int __init ragile_platform_init(void)
{
return 0;
}
static void __exit ragile_platform_exit(void)
{
}
module_init(ragile_platform_init);
module_exit(ragile_platform_exit);
MODULE_DESCRIPTION("ragile Platform Support");
MODULE_AUTHOR("tangjiamiao <support@ragilenetworks.com>");
MODULE_LICENSE("GPL");

View File

@ -1,858 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* at24.c - handle most I2C EEPROMs
*
* Copyright (C) 2005-2007 David Brownell
* Copyright (C) 2008 Wolfram Sang, Pengutronix
*/
#include <linux/acpi.h>
#include <linux/bitops.h>
#include <linux/capability.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/nvmem-provider.h>
#include <linux/of_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
/* Address pointer is 16 bit. */
#define AT24_FLAG_ADDR16 BIT(7)
/* sysfs-entry will be read-only. */
#define AT24_FLAG_READONLY BIT(6)
/* sysfs-entry will be world-readable. */
#define AT24_FLAG_IRUGO BIT(5)
/* Take always 8 addresses (24c00). */
#define AT24_FLAG_TAKE8ADDR BIT(4)
/* Factory-programmed serial number. */
#define AT24_FLAG_SERIAL BIT(3)
/* Factory-programmed mac address. */
#define AT24_FLAG_MAC BIT(2)
/* Does not auto-rollover reads to the next slave address. */
#define AT24_FLAG_NO_RDROL BIT(1)
/*
* I2C EEPROMs from most vendors are inexpensive and mostly interchangeable.
* Differences between different vendor product lines (like Atmel AT24C or
* MicroChip 24LC, etc) won't much matter for typical read/write access.
* There are also I2C RAM chips, likewise interchangeable. One example
* would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes).
*
* However, misconfiguration can lose data. "Set 16-bit memory address"
* to a part with 8-bit addressing will overwrite data. Writing with too
* big a page size also loses data. And it's not safe to assume that the
* conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC
* uses 0x51, for just one example.
*
* Accordingly, explicit board-specific configuration data should be used
* in almost all cases. (One partial exception is an SMBus used to access
* "SPD" data for DRAM sticks. Those only use 24c02 EEPROMs.)
*
* So this driver uses "new style" I2C driver binding, expecting to be
* told what devices exist. That may be in arch/X/mach-Y/board-Z.c or
* similar kernel-resident tables; or, configuration data coming from
* a bootloader.
*
* Other than binding model, current differences from "eeprom" driver are
* that this one handles write access and isn't restricted to 24c02 devices.
* It also handles larger devices (32 kbit and up) with two-byte addresses,
* which won't work on pure SMBus systems.
*/
struct at24_client {
struct i2c_client *client;
struct regmap *regmap;
};
struct at24_data {
/*
* Lock protects against activities from other Linux tasks,
* but not from changes by other I2C masters.
*/
struct mutex lock;
unsigned int write_max;
unsigned int num_addresses;
unsigned int offset_adj;
u32 byte_len;
u16 page_size;
u8 flags;
struct nvmem_device *nvmem;
struct regulator *vcc_reg;
void (*read_post)(unsigned int off, char *buf, size_t count);
/*
* Some chips tie up multiple I2C addresses; dummy devices reserve
* them for us, and we'll use them with SMBus calls.
*/
struct at24_client client[];
};
/*
* 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 int at24_io_limit = 128;
module_param_named(io_limit, at24_io_limit, uint, 0);
MODULE_PARM_DESC(at24_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 int at24_write_timeout = 25;
module_param_named(write_timeout, at24_write_timeout, uint, 0);
MODULE_PARM_DESC(at24_write_timeout, "Time (in ms) to try writes (default 25)");
struct at24_chip_data {
u32 byte_len;
u8 flags;
void (*read_post)(unsigned int off, char *buf, size_t count);
};
#define AT24_CHIP_DATA(_name, _len, _flags) \
static const struct at24_chip_data _name = { \
.byte_len = _len, .flags = _flags, \
}
#define AT24_CHIP_DATA_CB(_name, _len, _flags, _read_post) \
static const struct at24_chip_data _name = { \
.byte_len = _len, .flags = _flags, \
.read_post = _read_post, \
}
static void at24_read_post_vaio(unsigned int off, char *buf, size_t count)
{
int i;
if (capable(CAP_SYS_ADMIN))
return;
/*
* Hide VAIO private settings to regular users:
* - BIOS passwords: bytes 0x00 to 0x0f
* - UUID: bytes 0x10 to 0x1f
* - Serial number: 0xc0 to 0xdf
*/
for (i = 0; i < count; i++) {
if ((off + i <= 0x1f) ||
(off + i >= 0xc0 && off + i <= 0xdf))
buf[i] = 0;
}
}
/* needs 8 addresses as A0-A2 are ignored */
AT24_CHIP_DATA(at24_data_24c00, 128 / 8, AT24_FLAG_TAKE8ADDR);
/* old variants can't be handled with this generic entry! */
AT24_CHIP_DATA(at24_data_24c01, 1024 / 8, 0);
AT24_CHIP_DATA(at24_data_24cs01, 16,
AT24_FLAG_SERIAL | AT24_FLAG_READONLY);
AT24_CHIP_DATA(at24_data_24c02, 2048 / 8, AT24_FLAG_IRUGO);
AT24_CHIP_DATA(at24_data_24cs02, 16,
AT24_FLAG_SERIAL | AT24_FLAG_READONLY);
AT24_CHIP_DATA(at24_data_24mac402, 48 / 8,
AT24_FLAG_MAC | AT24_FLAG_READONLY);
AT24_CHIP_DATA(at24_data_24mac602, 64 / 8,
AT24_FLAG_MAC | AT24_FLAG_READONLY);
/* spd is a 24c02 in memory DIMMs */
AT24_CHIP_DATA(at24_data_spd, 2048 / 8,
AT24_FLAG_READONLY | AT24_FLAG_IRUGO);
/* 24c02_vaio is a 24c02 on some Sony laptops */
AT24_CHIP_DATA_CB(at24_data_24c02_vaio, 2048 / 8,
AT24_FLAG_READONLY | AT24_FLAG_IRUGO,
at24_read_post_vaio);
AT24_CHIP_DATA(at24_data_24c04, 4096 / 8, 0);
AT24_CHIP_DATA(at24_data_24cs04, 16,
AT24_FLAG_SERIAL | AT24_FLAG_READONLY);
/* 24rf08 quirk is handled at i2c-core */
AT24_CHIP_DATA(at24_data_24c08, 8192 / 8, 0);
AT24_CHIP_DATA(at24_data_24cs08, 16,
AT24_FLAG_SERIAL | AT24_FLAG_READONLY);
AT24_CHIP_DATA(at24_data_24c16, 16384 / 8, 0);
AT24_CHIP_DATA(at24_data_24cs16, 16,
AT24_FLAG_SERIAL | AT24_FLAG_READONLY);
AT24_CHIP_DATA(at24_data_24c32, 32768 / 8, AT24_FLAG_ADDR16);
AT24_CHIP_DATA(at24_data_24cs32, 16,
AT24_FLAG_ADDR16 | AT24_FLAG_SERIAL | AT24_FLAG_READONLY);
AT24_CHIP_DATA(at24_data_24c64, 65536 / 8, AT24_FLAG_ADDR16 | AT24_FLAG_IRUGO);
AT24_CHIP_DATA(at24_data_24cs64, 16,
AT24_FLAG_ADDR16 | AT24_FLAG_SERIAL | AT24_FLAG_READONLY);
AT24_CHIP_DATA(at24_data_24c128, 131072 / 8, AT24_FLAG_ADDR16);
AT24_CHIP_DATA(at24_data_24c256, 262144 / 8, AT24_FLAG_ADDR16);
AT24_CHIP_DATA(at24_data_24c512, 524288 / 8, AT24_FLAG_ADDR16);
AT24_CHIP_DATA(at24_data_24c1024, 1048576 / 8, AT24_FLAG_ADDR16);
AT24_CHIP_DATA(at24_data_24c2048, 2097152 / 8, AT24_FLAG_ADDR16);
/* identical to 24c08 ? */
AT24_CHIP_DATA(at24_data_INT3499, 8192 / 8, 0);
static const struct i2c_device_id at24_ids[] = {
{ "rg_24c00", (kernel_ulong_t)&at24_data_24c00 },
{ "rg_24c01", (kernel_ulong_t)&at24_data_24c01 },
{ "rg_24cs01", (kernel_ulong_t)&at24_data_24cs01 },
{ "rg_24c02", (kernel_ulong_t)&at24_data_24c02 },
{ "rg_24cs02", (kernel_ulong_t)&at24_data_24cs02 },
{ "rg_24mac402", (kernel_ulong_t)&at24_data_24mac402 },
{ "rg_24mac602", (kernel_ulong_t)&at24_data_24mac602 },
{ "rg_spd", (kernel_ulong_t)&at24_data_spd },
{ "rg_24c02-vaio", (kernel_ulong_t)&at24_data_24c02_vaio },
{ "rg_24c04", (kernel_ulong_t)&at24_data_24c04 },
{ "rg_24cs04", (kernel_ulong_t)&at24_data_24cs04 },
{ "rg_24c08", (kernel_ulong_t)&at24_data_24c08 },
{ "rg_24cs08", (kernel_ulong_t)&at24_data_24cs08 },
{ "rg_24c16", (kernel_ulong_t)&at24_data_24c16 },
{ "rg_24cs16", (kernel_ulong_t)&at24_data_24cs16 },
{ "rg_24c32", (kernel_ulong_t)&at24_data_24c32 },
{ "rg_24cs32", (kernel_ulong_t)&at24_data_24cs32 },
{ "rg_24c64", (kernel_ulong_t)&at24_data_24c64 },
{ "rg_24cs64", (kernel_ulong_t)&at24_data_24cs64 },
{ "rg_24c128", (kernel_ulong_t)&at24_data_24c128 },
{ "rg_24c256", (kernel_ulong_t)&at24_data_24c256 },
{ "rg_24c512", (kernel_ulong_t)&at24_data_24c512 },
{ "rg_24c1024", (kernel_ulong_t)&at24_data_24c1024 },
{ "rg_24c2048", (kernel_ulong_t)&at24_data_24c2048 },
{ "rg_at24", 0 },
{ /* END OF LIST */ }
};
MODULE_DEVICE_TABLE(i2c, at24_ids);
static const struct of_device_id at24_of_match[] = {
{ .compatible = "atmel,24c00", .data = &at24_data_24c00 },
{ .compatible = "atmel,24c01", .data = &at24_data_24c01 },
{ .compatible = "atmel,24cs01", .data = &at24_data_24cs01 },
{ .compatible = "atmel,24c02", .data = &at24_data_24c02 },
{ .compatible = "atmel,24cs02", .data = &at24_data_24cs02 },
{ .compatible = "atmel,24mac402", .data = &at24_data_24mac402 },
{ .compatible = "atmel,24mac602", .data = &at24_data_24mac602 },
{ .compatible = "atmel,spd", .data = &at24_data_spd },
{ .compatible = "atmel,24c04", .data = &at24_data_24c04 },
{ .compatible = "atmel,24cs04", .data = &at24_data_24cs04 },
{ .compatible = "atmel,24c08", .data = &at24_data_24c08 },
{ .compatible = "atmel,24cs08", .data = &at24_data_24cs08 },
{ .compatible = "atmel,24c16", .data = &at24_data_24c16 },
{ .compatible = "atmel,24cs16", .data = &at24_data_24cs16 },
{ .compatible = "atmel,24c32", .data = &at24_data_24c32 },
{ .compatible = "atmel,24cs32", .data = &at24_data_24cs32 },
{ .compatible = "atmel,24c64", .data = &at24_data_24c64 },
{ .compatible = "atmel,24cs64", .data = &at24_data_24cs64 },
{ .compatible = "atmel,24c128", .data = &at24_data_24c128 },
{ .compatible = "atmel,24c256", .data = &at24_data_24c256 },
{ .compatible = "atmel,24c512", .data = &at24_data_24c512 },
{ .compatible = "atmel,24c1024", .data = &at24_data_24c1024 },
{ .compatible = "atmel,24c2048", .data = &at24_data_24c2048 },
{ /* END OF LIST */ },
};
MODULE_DEVICE_TABLE(of, at24_of_match);
static const struct acpi_device_id __maybe_unused at24_acpi_ids[] = {
{ "INT3499", (kernel_ulong_t)&at24_data_INT3499 },
{ "TPF0001", (kernel_ulong_t)&at24_data_24c1024 },
{ /* END OF LIST */ }
};
MODULE_DEVICE_TABLE(acpi, at24_acpi_ids);
/*
* This routine supports chips which consume multiple I2C addresses. It
* computes the addressing information to be used for a given r/w request.
* Assumes that sanity checks for offset happened at sysfs-layer.
*
* Slave address and byte offset derive from the offset. Always
* set the byte address; on a multi-master board, another master
* may have changed the chip's "current" address pointer.
*/
static struct at24_client *at24_translate_offset(struct at24_data *at24,
unsigned int *offset)
{
unsigned int i;
if (at24->flags & AT24_FLAG_ADDR16) {
i = *offset >> 16;
*offset &= 0xffff;
} else {
i = *offset >> 8;
*offset &= 0xff;
}
return &at24->client[i];
}
static struct device *at24_base_client_dev(struct at24_data *at24)
{
return &at24->client[0].client->dev;
}
static size_t at24_adjust_read_count(struct at24_data *at24,
unsigned int offset, size_t count)
{
unsigned int bits;
size_t remainder;
/*
* In case of multi-address chips that don't rollover reads to
* the next slave address: truncate the count to the slave boundary,
* so that the read never straddles slaves.
*/
if (at24->flags & AT24_FLAG_NO_RDROL) {
bits = (at24->flags & AT24_FLAG_ADDR16) ? 16 : 8;
remainder = BIT(bits) - offset;
if (count > remainder)
count = remainder;
}
if (count > at24_io_limit)
count = at24_io_limit;
return count;
}
static ssize_t at24_regmap_read(struct at24_data *at24, char *buf,
unsigned int offset, size_t count)
{
unsigned long timeout, read_time;
struct at24_client *at24_client;
struct i2c_client *client;
struct regmap *regmap;
int ret;
at24_client = at24_translate_offset(at24, &offset);
regmap = at24_client->regmap;
client = at24_client->client;
count = at24_adjust_read_count(at24, offset, count);
/* adjust offset for mac and serial read ops */
offset += at24->offset_adj;
timeout = jiffies + msecs_to_jiffies(at24_write_timeout);
do {
/*
* The timestamp shall be taken before the actual operation
* to avoid a premature timeout in case of high CPU load.
*/
read_time = jiffies;
ret = regmap_bulk_read(regmap, offset, buf, count);
dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n",
count, offset, ret, jiffies);
if (!ret)
return count;
usleep_range(1000, 1500);
} while (time_before(read_time, timeout));
return -ETIMEDOUT;
}
/*
* Note that if the hardware write-protect pin is pulled high, the whole
* chip is normally write protected. But there are plenty of product
* variants here, including OTP fuses and partial chip protect.
*
* We only use page mode writes; the alternative is sloooow. These routines
* write at most one page.
*/
static size_t at24_adjust_write_count(struct at24_data *at24,
unsigned int offset, size_t count)
{
unsigned int next_page;
/* write_max is at most a page */
if (count > at24->write_max)
count = at24->write_max;
/* Never roll over backwards, to the start of this page */
next_page = roundup(offset + 1, at24->page_size);
if (offset + count > next_page)
count = next_page - offset;
return count;
}
static ssize_t at24_regmap_write(struct at24_data *at24, const char *buf,
unsigned int offset, size_t count)
{
unsigned long timeout, write_time;
struct at24_client *at24_client;
struct i2c_client *client;
struct regmap *regmap;
int ret;
at24_client = at24_translate_offset(at24, &offset);
regmap = at24_client->regmap;
client = at24_client->client;
count = at24_adjust_write_count(at24, offset, count);
timeout = jiffies + msecs_to_jiffies(at24_write_timeout);
do {
/*
* The timestamp shall be taken before the actual operation
* to avoid a premature timeout in case of high CPU load.
*/
write_time = jiffies;
ret = regmap_bulk_write(regmap, offset, buf, count);
dev_dbg(&client->dev, "write %zu@%d --> %d (%ld)\n",
count, offset, ret, jiffies);
if (!ret)
return count;
usleep_range(1000, 1500);
} while (time_before(write_time, timeout));
return -ETIMEDOUT;
}
static int at24_read(void *priv, unsigned int off, void *val, size_t count)
{
struct at24_data *at24;
struct device *dev;
char *buf = val;
int i, ret;
at24 = priv;
dev = at24_base_client_dev(at24);
if (unlikely(!count))
return count;
if (off + count > at24->byte_len)
return -EINVAL;
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
pm_runtime_put_noidle(dev);
return ret;
}
/*
* Read data from chip, protecting against concurrent updates
* from this host, but not from other I2C masters.
*/
mutex_lock(&at24->lock);
for (i = 0; count; i += ret, count -= ret) {
ret = at24_regmap_read(at24, buf + i, off + i, count);
if (ret < 0) {
mutex_unlock(&at24->lock);
pm_runtime_put(dev);
return ret;
}
}
mutex_unlock(&at24->lock);
pm_runtime_put(dev);
if (unlikely(at24->read_post))
at24->read_post(off, buf, i);
return 0;
}
static int at24_write(void *priv, unsigned int off, void *val, size_t count)
{
struct at24_data *at24;
struct device *dev;
char *buf = val;
int ret;
at24 = priv;
dev = at24_base_client_dev(at24);
if (unlikely(!count))
return -EINVAL;
if (off + count > at24->byte_len)
return -EINVAL;
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
pm_runtime_put_noidle(dev);
return ret;
}
/*
* Write data to chip, protecting against concurrent updates
* from this host, but not from other I2C masters.
*/
mutex_lock(&at24->lock);
while (count) {
ret = at24_regmap_write(at24, buf, off, count);
if (ret < 0) {
mutex_unlock(&at24->lock);
pm_runtime_put(dev);
return ret;
}
buf += ret;
off += ret;
count -= ret;
}
mutex_unlock(&at24->lock);
pm_runtime_put(dev);
return 0;
}
static const struct at24_chip_data *at24_get_chip_data(struct device *dev)
{
struct device_node *of_node = dev->of_node;
const struct at24_chip_data *cdata;
const struct i2c_device_id *id;
id = i2c_match_id(at24_ids, to_i2c_client(dev));
/*
* The I2C core allows OF nodes compatibles to match against the
* I2C device ID table as a fallback, so check not only if an OF
* node is present but also if it matches an OF device ID entry.
*/
if (of_node && of_match_device(at24_of_match, dev))
cdata = of_device_get_match_data(dev);
else if (id)
cdata = (void *)id->driver_data;
else
cdata = acpi_device_get_match_data(dev);
if (!cdata)
return ERR_PTR(-ENODEV);
return cdata;
}
static int at24_make_dummy_client(struct at24_data *at24, unsigned int index,
struct regmap_config *regmap_config)
{
struct i2c_client *base_client, *dummy_client;
struct regmap *regmap;
struct device *dev;
base_client = at24->client[0].client;
dev = &base_client->dev;
dummy_client = devm_i2c_new_dummy_device(dev, base_client->adapter,
base_client->addr + index);
if (IS_ERR(dummy_client))
return PTR_ERR(dummy_client);
regmap = devm_regmap_init_i2c(dummy_client, regmap_config);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
at24->client[index].client = dummy_client;
at24->client[index].regmap = regmap;
return 0;
}
static unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len)
{
if (flags & AT24_FLAG_MAC) {
/* EUI-48 starts from 0x9a, EUI-64 from 0x98 */
return 0xa0 - byte_len;
} else if (flags & AT24_FLAG_SERIAL && flags & AT24_FLAG_ADDR16) {
/*
* For 16 bit address pointers, the word address must contain
* a '10' sequence in bits 11 and 10 regardless of the
* intended position of the address pointer.
*/
return 0x0800;
} else if (flags & AT24_FLAG_SERIAL) {
/*
* Otherwise the word address must begin with a '10' sequence,
* regardless of the intended address.
*/
return 0x0080;
} else {
return 0;
}
}
static int at24_probe(struct i2c_client *client)
{
struct regmap_config regmap_config = { };
struct nvmem_config nvmem_config = { };
u32 byte_len, page_size, flags, addrw;
const struct at24_chip_data *cdata;
struct device *dev = &client->dev;
bool i2c_fn_i2c, i2c_fn_block;
unsigned int i, num_addresses;
struct at24_data *at24;
struct regmap *regmap;
bool writable;
u8 test_byte;
int err;
i2c_fn_i2c = i2c_check_functionality(client->adapter, I2C_FUNC_I2C);
i2c_fn_block = i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_WRITE_I2C_BLOCK);
cdata = at24_get_chip_data(dev);
if (IS_ERR(cdata))
return PTR_ERR(cdata);
err = device_property_read_u32(dev, "pagesize", &page_size);
if (err)
/*
* This is slow, but we can't know all eeproms, so we better
* play safe. Specifying custom eeprom-types via device tree
* or properties is recommended anyhow.
*/
page_size = 1;
flags = cdata->flags;
if (device_property_present(dev, "read-only"))
flags |= AT24_FLAG_READONLY;
if (device_property_present(dev, "no-read-rollover"))
flags |= AT24_FLAG_NO_RDROL;
err = device_property_read_u32(dev, "address-width", &addrw);
if (!err) {
switch (addrw) {
case 8:
if (flags & AT24_FLAG_ADDR16)
dev_warn(dev,
"Override address width to be 8, while default is 16\n");
flags &= ~AT24_FLAG_ADDR16;
break;
case 16:
flags |= AT24_FLAG_ADDR16;
break;
default:
dev_warn(dev, "Bad \"address-width\" property: %u\n",
addrw);
}
}
err = device_property_read_u32(dev, "size", &byte_len);
if (err)
byte_len = cdata->byte_len;
if (!i2c_fn_i2c && !i2c_fn_block)
page_size = 1;
if (!page_size) {
dev_err(dev, "page_size must not be 0!\n");
return -EINVAL;
}
if (!is_power_of_2(page_size))
dev_warn(dev, "page_size looks suspicious (no power of 2)!\n");
err = device_property_read_u32(dev, "num-addresses", &num_addresses);
if (err) {
if (flags & AT24_FLAG_TAKE8ADDR)
num_addresses = 8;
else
num_addresses = DIV_ROUND_UP(byte_len,
(flags & AT24_FLAG_ADDR16) ? 65536 : 256);
}
if ((flags & AT24_FLAG_SERIAL) && (flags & AT24_FLAG_MAC)) {
dev_err(dev,
"invalid device data - cannot have both AT24_FLAG_SERIAL & AT24_FLAG_MAC.");
return -EINVAL;
}
regmap_config.val_bits = 8;
regmap_config.reg_bits = (flags & AT24_FLAG_ADDR16) ? 16 : 8;
regmap_config.disable_locking = true;
regmap = devm_regmap_init_i2c(client, &regmap_config);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
at24 = devm_kzalloc(dev, struct_size(at24, client, num_addresses),
GFP_KERNEL);
if (!at24)
return -ENOMEM;
mutex_init(&at24->lock);
at24->byte_len = byte_len;
at24->page_size = page_size;
at24->flags = flags;
at24->read_post = cdata->read_post;
at24->num_addresses = num_addresses;
at24->offset_adj = at24_get_offset_adj(flags, byte_len);
at24->client[0].client = client;
at24->client[0].regmap = regmap;
at24->vcc_reg = devm_regulator_get(dev, "vcc");
if (IS_ERR(at24->vcc_reg))
return PTR_ERR(at24->vcc_reg);
writable = !(flags & AT24_FLAG_READONLY);
if (writable) {
at24->write_max = min_t(unsigned int,
page_size, at24_io_limit);
if (!i2c_fn_i2c && at24->write_max > I2C_SMBUS_BLOCK_MAX)
at24->write_max = I2C_SMBUS_BLOCK_MAX;
}
/* use dummy devices for multiple-address chips */
for (i = 1; i < num_addresses; i++) {
err = at24_make_dummy_client(at24, i, &regmap_config);
if (err)
return err;
}
/*
* If the 'label' property is not present for the AT24 EEPROM,
* then nvmem_config.id is initialised to NVMEM_DEVID_AUTO,
* and this will append the 'devid' to the name of the NVMEM
* device. This is purely legacy and the AT24 driver has always
* defaulted to this. However, if the 'label' property is
*/
nvmem_config.id = NVMEM_DEVID_AUTO;
if (device_property_present(dev, "label")) {
err = device_property_read_string(dev, "label",
&nvmem_config.name);
if (err)
return err;
} else {
nvmem_config.name = dev_name(dev);
}
nvmem_config.type = NVMEM_TYPE_EEPROM;
nvmem_config.dev = dev;
nvmem_config.read_only = !writable;
nvmem_config.root_only = !(flags & AT24_FLAG_IRUGO);
nvmem_config.owner = THIS_MODULE;
nvmem_config.compat = true;
nvmem_config.base_dev = dev;
nvmem_config.reg_read = at24_read;
nvmem_config.reg_write = at24_write;
nvmem_config.priv = at24;
nvmem_config.stride = 1;
nvmem_config.word_size = 1;
nvmem_config.size = byte_len;
i2c_set_clientdata(client, at24);
err = regulator_enable(at24->vcc_reg);
if (err) {
dev_err(dev, "Failed to enable vcc regulator\n");
return err;
}
/* enable runtime pm */
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
if (IS_ERR(at24->nvmem)) {
pm_runtime_disable(dev);
if (!pm_runtime_status_suspended(dev))
regulator_disable(at24->vcc_reg);
return PTR_ERR(at24->nvmem);
}
/*
* Perform a one-byte test read to verify that the
* chip is functional.
*/
err = at24_read(at24, 0, &test_byte, 1);
if (err) {
pm_runtime_disable(dev);
if (!pm_runtime_status_suspended(dev))
regulator_disable(at24->vcc_reg);
return -ENODEV;
}
pm_runtime_idle(dev);
if (writable)
dev_info(dev, "%u byte %s EEPROM, writable, %u bytes/write\n",
byte_len, client->name, at24->write_max);
else
dev_info(dev, "%u byte %s EEPROM, read-only\n",
byte_len, client->name);
return 0;
}
static int at24_remove(struct i2c_client *client)
{
struct at24_data *at24 = i2c_get_clientdata(client);
pm_runtime_disable(&client->dev);
if (!pm_runtime_status_suspended(&client->dev))
regulator_disable(at24->vcc_reg);
pm_runtime_set_suspended(&client->dev);
return 0;
}
static int __maybe_unused at24_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct at24_data *at24 = i2c_get_clientdata(client);
return regulator_disable(at24->vcc_reg);
}
static int __maybe_unused at24_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct at24_data *at24 = i2c_get_clientdata(client);
return regulator_enable(at24->vcc_reg);
}
static const struct dev_pm_ops at24_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume)
SET_RUNTIME_PM_OPS(at24_suspend, at24_resume, NULL)
};
static struct i2c_driver at24_driver = {
.driver = {
.name = "rg_at24",
.pm = &at24_pm_ops,
.of_match_table = at24_of_match,
.acpi_match_table = ACPI_PTR(at24_acpi_ids),
},
.probe_new = at24_probe,
.remove = at24_remove,
.id_table = at24_ids,
};
static int __init at24_init(void)
{
if (!at24_io_limit) {
pr_err("at24: at24_io_limit must not be 0!\n");
return -EINVAL;
}
at24_io_limit = rounddown_pow_of_two(at24_io_limit);
return i2c_add_driver(&at24_driver);
}
module_init(at24_init);
static void __exit at24_exit(void)
{
i2c_del_driver(&at24_driver);
}
module_exit(at24_exit);
MODULE_DESCRIPTION("Driver for most I2C EEPROMs");
MODULE_AUTHOR("David Brownell and Wolfram Sang");
MODULE_LICENSE("GPL");

View File

@ -1,91 +0,0 @@
/*
* EEPROMs access control driver for display configuration EEPROMs
* on DigsyMTC board.
*
* (C) 2011 DENX Software Engineering, Anatolij Gustschin <agust@denx.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_gpio.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/spi/eeprom.h>
#include <linux/spi/flash.h>
#define GPIO_TPM_CLK 496
#define GPIO_TPM_CS 500
#define GPIO_TPM_DI 499
#define GPIO_TPM_DO 498
#define EE_SPI_BUS_NUM 1
static struct spi_gpio_platform_data tpm_spi_gpio_data = {
.sck = GPIO_TPM_CLK,
.mosi = GPIO_TPM_DI,
.miso = GPIO_TPM_DO,
.num_chipselect = 2,
};
static void spi_gpio_release(struct device *dev)
{
return;
}
static struct platform_device tpm_device = {
.name = "spi_gpio",
.id = 3,
.dev = {
.platform_data = &tpm_spi_gpio_data,
.release = spi_gpio_release,
}
};
static struct spi_board_info tpm_info = {
.modalias = "tpm_tis_spi",
.max_speed_hz = 1000000,
.bus_num = 3,
.chip_select = 0, /* 0 ,1 */
.mode = SPI_MODE_0,
.controller_data = (void *)GPIO_TPM_CS,
};
static int __init tpm_devices_init(void)
{
int ret;
struct spi_master *master;
ret = platform_device_register(&tpm_device);
if (ret) {
printk("can't add spi-gpio device \n");
return ret;
}
master = spi_busnum_to_master(tpm_info.bus_num);
if( !master ) {
return -ENODEV;
}
printk(KERN_INFO "enter tpm_devices_init. \n");
spi_new_device(master, &tpm_info);
return 0 ;
}
static void __exit tpm_devices_exit(void)
{
platform_device_unregister(&tpm_device);
}
module_init(tpm_devices_init);
module_exit(tpm_devices_exit);
MODULE_DESCRIPTION("ragile spi gpio device Support");
MODULE_AUTHOR("support@ragilenetworks.com");
MODULE_LICENSE("GPL");

View File

@ -1,258 +0,0 @@
/*
* An I2C driver for the PCF85063 RTC
* Copyright 2014 Rose Technology
*
* Author: Sren Andersen <san@rosetechnology.dk>
* Maintainers: http://www.nslu2-linux.org/
*
* based on the other drivers in this same directory.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/i2c.h>
#include <linux/bcd.h>
#include <linux/rtc.h>
#include <linux/module.h>
/*
* Information for this driver was pulled from the following datasheets.
*
* http://www.nxp.com/documents/data_sheet/PCF85063A.pdf
* http://www.nxp.com/documents/data_sheet/PCF85063TP.pdf
*
*/
#define PCF85063_REG_CTRL1 0x00 /* status */
#define PCF85063_REG_CTRL1_CAP_SEL BIT(0)
#define PCF85063_REG_CTRL1_STOP BIT(5)
#define PCF85063_REG_CTRL2 0x01
#define PCF85063_REG_CTRL2_COF 0x07
#define PCF85063_REG_SC 0x04 /* datetime */
#define PCF85063_REG_SC_OS 0x80
#define PCF85063_REG_MN 0x05
#define PCF85063_REG_HR 0x06
#define PCF85063_REG_DM 0x07
#define PCF85063_REG_DW 0x08
#define PCF85063_REG_MO 0x09
#define PCF85063_REG_YR 0x0A
#define PCF85063_SR 0x58
static struct i2c_driver pcf85063_driver;
static int pcf85063_stop_clock(struct i2c_client *client, u8 *ctrl1)
{
s32 ret;
ret = i2c_smbus_read_byte_data(client, PCF85063_REG_CTRL1);
if (ret < 0) {
dev_err(&client->dev, "Failing to stop the clock\n");
return -EIO;
}
/* stop the clock */
ret |= PCF85063_REG_CTRL1_STOP;
ret = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, ret);
if (ret < 0) {
dev_err(&client->dev, "Failing to stop the clock\n");
return -EIO;
}
*ctrl1 = ret;
return 0;
}
static int pcf85063_start_clock(struct i2c_client *client, u8 ctrl1)
{
s32 ret;
/* start the clock */
ctrl1 &= ~PCF85063_REG_CTRL1_STOP;
ret = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, ctrl1);
if (ret < 0) {
dev_err(&client->dev, "Failing to start the clock\n");
return -EIO;
}
return 0;
}
static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm)
{
int rc;
u8 regs[7];
/*
* while reading, the time/date registers are blocked and not updated
* anymore until the access is finished. To not lose a second
* event, the access must be finished within one second. So, read all
* time/date registers in one turn.
*/
rc = i2c_smbus_read_i2c_block_data(client, PCF85063_REG_SC,
sizeof(regs), regs);
if (rc != sizeof(regs)) {
dev_err(&client->dev, "date/time register read error\n");
return -EIO;
}
/* if the clock has lost its power it makes no sense to use its time */
if (regs[0] & PCF85063_REG_SC_OS) {
dev_warn(&client->dev, "Power loss detected, invalid time\n");
return -EINVAL;
}
tm->tm_sec = bcd2bin(regs[0] & 0x7F);
tm->tm_min = bcd2bin(regs[1] & 0x7F);
tm->tm_hour = bcd2bin(regs[2] & 0x3F); /* rtc hr 0-23 */
tm->tm_mday = bcd2bin(regs[3] & 0x3F);
tm->tm_wday = regs[4] & 0x07;
tm->tm_mon = bcd2bin(regs[5] & 0x1F) - 1; /* rtc mn 1-12 */
tm->tm_year = bcd2bin(regs[6]);
tm->tm_year += 100;
return rtc_valid_tm(tm);
}
static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm)
{
int rc;
u8 regs[7];
u8 ctrl1;
u8 cof;
s32 err;
cof = 0;
cof |= PCF85063_REG_CTRL2_COF;
if ((tm->tm_year < 100) || (tm->tm_year > 199))
return -EINVAL;
/* reset rtc-pcf85063 */
err = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, PCF85063_SR);
if (err < 0) {
dev_err(&client->dev, "Failing to reset rtc-pcf85063\n");
return EIO;
}
/*
* to accurately set the time, reset the divider chain and keep it in
* reset state until all time/date registers are written
*/
rc = pcf85063_stop_clock(client, &ctrl1);
if (rc != 0)
return rc;
/* set CTRL1 CAP_SEL is 12.5pF */
ctrl1 |= PCF85063_REG_CTRL1_CAP_SEL;
err = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, ctrl1);
if (err < 0) {
dev_err(&client->dev, "Failing to write the PCF85063_REG_CTRL1\n");
return -EIO;
}
/* set CTRL2 CLKOUT is LOW */
err = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL2, cof);
if (err < 0) {
dev_err(&client->dev, "Failing to write the PCF85063_REG_CTRL2\n");
return -EIO;
}
/* hours, minutes and seconds */
regs[0] = bin2bcd(tm->tm_sec) & 0x7F; /* clear OS flag */
regs[1] = bin2bcd(tm->tm_min);
regs[2] = bin2bcd(tm->tm_hour);
/* Day of month, 1 - 31 */
regs[3] = bin2bcd(tm->tm_mday);
/* Day, 0 - 6 */
regs[4] = tm->tm_wday & 0x07;
/* month, 1 - 12 */
regs[5] = bin2bcd(tm->tm_mon + 1);
/* year and century */
regs[6] = bin2bcd(tm->tm_year - 100);
/* write all registers at once */
rc = i2c_smbus_write_i2c_block_data(client, PCF85063_REG_SC,
sizeof(regs), regs);
if (rc < 0) {
dev_err(&client->dev, "date/time register write error\n");
return rc;
}
/*
* Write the control register as a separate action since the size of
* the register space is different between the PCF85063TP and
* PCF85063A devices. The rollover point can not be used.
*/
rc = pcf85063_start_clock(client, ctrl1);
if (rc != 0)
return rc;
return 0;
}
static int pcf85063_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
return pcf85063_get_datetime(to_i2c_client(dev), tm);
}
static int pcf85063_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
return pcf85063_set_datetime(to_i2c_client(dev), tm);
}
static const struct rtc_class_ops pcf85063_rtc_ops = {
.read_time = pcf85063_rtc_read_time,
.set_time = pcf85063_rtc_set_time
};
static int pcf85063_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct rtc_device *rtc;
dev_dbg(&client->dev, "%s\n", __func__);
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV;
rtc = devm_rtc_device_register(&client->dev,
pcf85063_driver.driver.name,
&pcf85063_rtc_ops, THIS_MODULE);
rtc->uie_unsupported = 1;
return PTR_ERR_OR_ZERO(rtc);
}
static const struct i2c_device_id pcf85063_id[] = {
{ "rtcpcf85063", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, pcf85063_id);
static const struct of_device_id pcf85063_of_match[] = {
{ .compatible = "nxp,rtcpcf85063" },
{}
};
MODULE_DEVICE_TABLE(of, pcf85063_of_match);
static struct i2c_driver pcf85063_driver = {
.driver = {
.name = "rtcpcf85063",
.of_match_table = of_match_ptr(pcf85063_of_match),
},
.probe = pcf85063_probe,
.id_table = pcf85063_id,
};
module_i2c_driver(pcf85063_driver);
MODULE_AUTHOR("Sren Andersen <san@rosetechnology.dk>");
MODULE_DESCRIPTION("PCF85063 RTC driver");
MODULE_LICENSE("GPL");

View File

@ -1,107 +0,0 @@
/*
* Mix this utility code with some glue code to get one of several types of
* simple SPI master driver. Two do polled word-at-a-time I/O:
*
* - GPIO/parport bitbangers. Provide chipselect() and txrx_word[](),
* expanding the per-word routines from the inline templates below.
*
* - Drivers for controllers resembling bare shift registers. Provide
* chipselect() and txrx_word[](), with custom setup()/cleanup() methods
* that use your controller's clock and chipselect registers.
*
* Some hardware works well with requests at spi_transfer scope:
*
* - Drivers leveraging smarter hardware, with fifos or DMA; or for half
* duplex (MicroWire) controllers. Provide chipselect() and txrx_bufs(),
* and custom setup()/cleanup() methods.
*/
/*
* The code that knows what GPIO pins do what should have declared four
* functions, ideally as inlines, before including this header:
*
* void setsck(struct spi_device *, int is_on);
* void setmosi(struct spi_device *, int is_on);
* int getmiso(struct spi_device *);
* void spidelay(unsigned);
*
* setsck()'s is_on parameter is a zero/nonzero boolean.
*
* setmosi()'s is_on parameter is a zero/nonzero boolean.
*
* getmiso() is required to return 0 or 1 only. Any other value is invalid
* and will result in improper operation.
*
* A non-inlined routine would call bitbang_txrx_*() routines. The
* main loop could easily compile down to a handful of instructions,
* especially if the delay is a NOP (to run at peak speed).
*
* Since this is software, the timings may not be exactly what your board's
* chips need ... there may be several reasons you'd need to tweak timings
* in these routines, not just to make it faster or slower to match a
* particular CPU clock rate.
*/
static inline u32
bitbang_txrx_be_cpha0(struct spi_device *spi,
unsigned nsecs, unsigned cpol, unsigned flags,
u32 word, u8 bits)
{
/* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */
u32 oldbit = (!(word & (1<<(bits-1)))) << 31;
/* clock starts at inactive polarity */
for (word <<= (32 - bits); likely(bits); bits--) {
/* setup MSB (to slave) on trailing edge */
if ((flags & SPI_MASTER_NO_TX) == 0) {
if ((word & (1 << 31)) != oldbit) {
setmosi(spi, word & (1 << 31));
oldbit = word & (1 << 31);
}
}
spidelay(nsecs); /* T(setup) */
setsck(spi, !cpol);
spidelay(nsecs);
/* sample MSB (from slave) on leading edge */
word <<= 1;
if ((flags & SPI_MASTER_NO_RX) == 0)
word |= getmiso(spi);
setsck(spi, cpol);
}
return word;
}
static inline u32
bitbang_txrx_be_cpha1(struct spi_device *spi,
unsigned nsecs, unsigned cpol, unsigned flags,
u32 word, u8 bits)
{
/* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */
u32 oldbit = (!(word & (1<<(bits-1)))) << 31;
/* clock starts at inactive polarity */
for (word <<= (32 - bits); likely(bits); bits--) {
/* setup MSB (to slave) on leading edge */
setsck(spi, !cpol);
if ((flags & SPI_MASTER_NO_TX) == 0) {
if ((word & (1 << 31)) != oldbit) {
setmosi(spi, word & (1 << 31));
oldbit = word & (1 << 31);
}
}
spidelay(nsecs); /* T(setup) */
setsck(spi, cpol);
spidelay(nsecs);
/* sample MSB (from slave) on trailing edge */
word <<= 1;
if ((flags & SPI_MASTER_NO_RX) == 0)
word |= getmiso(spi);
}
return word;
}

View File

@ -1,546 +0,0 @@
/*
* SPI master driver using generic bitbanged GPIO
*
* Copyright (C) 2006,2008 David Brownell
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/spi/spi_gpio.h>
/*
* This bitbanging SPI master driver should help make systems usable
* when a native hardware SPI engine is not available, perhaps because
* its driver isn't yet working or because the I/O pins it requires
* are used for other purposes.
*
* platform_device->driver_data ... points to spi_gpio
*
* spi->controller_state ... reserved for bitbang framework code
* spi->controller_data ... holds chipselect GPIO
*
* spi->master->dev.driver_data ... points to spi_gpio->bitbang
*/
struct spi_gpio {
struct spi_bitbang bitbang;
struct spi_gpio_platform_data pdata;
struct platform_device *pdev;
unsigned long cs_gpios[0];
};
/*----------------------------------------------------------------------*/
/*
* Because the overhead of going through four GPIO procedure calls
* per transferred bit can make performance a problem, this code
* is set up so that you can use it in either of two ways:
*
* - The slow generic way: set up platform_data to hold the GPIO
* numbers used for MISO/MOSI/SCK, and issue procedure calls for
* each of them. This driver can handle several such busses.
*
* - The quicker inlined way: only helps with platform GPIO code
* that inlines operations for constant GPIOs. This can give
* you tight (fast!) inner loops, but each such bus needs a
* new driver. You'll define a new C file, with Makefile and
* Kconfig support; the C code can be a total of six lines:
*
* #define DRIVER_NAME "myboard_spi2"
* #define SPI_MISO_GPIO 119
* #define SPI_MOSI_GPIO 120
* #define SPI_SCK_GPIO 121
* #define SPI_N_CHIPSEL 4
* #include "spi-gpio.c"
*/
#ifndef DRIVER_NAME
#define DRIVER_NAME "spi_gpio"
#define GENERIC_BITBANG /* vs tight inlines */
/* all functions referencing these symbols must define pdata */
#define SPI_MISO_GPIO ((pdata)->miso)
#define SPI_MOSI_GPIO ((pdata)->mosi)
#define SPI_SCK_GPIO ((pdata)->sck)
#define SPI_N_CHIPSEL ((pdata)->num_chipselect)
#endif
/*----------------------------------------------------------------------*/
static inline struct spi_gpio *__pure
spi_to_spi_gpio(const struct spi_device *spi)
{
const struct spi_bitbang *bang;
struct spi_gpio *spi_gpio;
bang = spi_master_get_devdata(spi->master);
spi_gpio = container_of(bang, struct spi_gpio, bitbang);
return spi_gpio;
}
static inline struct spi_gpio_platform_data *__pure
spi_to_pdata(const struct spi_device *spi)
{
return &spi_to_spi_gpio(spi)->pdata;
}
/* this is #defined to avoid unused-variable warnings when inlining */
#define pdata spi_to_pdata(spi)
static inline void setsck(const struct spi_device *spi, int is_on)
{
gpio_set_value_cansleep(SPI_SCK_GPIO, is_on);
}
static inline void setmosi(const struct spi_device *spi, int is_on)
{
gpio_set_value_cansleep(SPI_MOSI_GPIO, is_on);
}
static inline int getmiso(const struct spi_device *spi)
{
return !!gpio_get_value_cansleep(SPI_MISO_GPIO);
}
#undef pdata
/*
* NOTE: this clocks "as fast as we can". It "should" be a function of the
* requested device clock. Software overhead means we usually have trouble
* reaching even one Mbit/sec (except when we can inline bitops), so for now
* we'll just assume we never need additional per-bit slowdowns.
*/
#define spidelay(nsecs) do {} while (0)
#include "spi-bitbang-txrx.h"
/*
* These functions can leverage inline expansion of GPIO calls to shrink
* costs for a txrx bit, often by factors of around ten (by instruction
* count). That is particularly visible for larger word sizes, but helps
* even with default 8-bit words.
*
* REVISIT overheads calling these functions for each word also have
* significant performance costs. Having txrx_bufs() calls that inline
* the txrx_word() logic would help performance, e.g. on larger blocks
* used with flash storage or MMC/SD. There should also be ways to make
* GCC be less stupid about reloading registers inside the I/O loops,
* even without inlined GPIO calls; __attribute__((hot)) on GCC 4.3?
*/
static u32 spi_gpio_txrx_word_mode0(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
}
static u32 spi_gpio_txrx_word_mode1(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits);
}
static u32 spi_gpio_txrx_word_mode2(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits);
}
static u32 spi_gpio_txrx_word_mode3(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits);
}
/*
* These functions do not call setmosi or getmiso if respective flag
* (SPI_MASTER_NO_RX or SPI_MASTER_NO_TX) is set, so they are safe to
* call when such pin is not present or defined in the controller.
* A separate set of callbacks is defined to get highest possible
* speed in the generic case (when both MISO and MOSI lines are
* available), as optimiser will remove the checks when argument is
* constant.
*/
static u32 spi_gpio_spec_txrx_word_mode0(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
unsigned flags = spi->master->flags;
return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits);
}
static u32 spi_gpio_spec_txrx_word_mode1(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
unsigned flags = spi->master->flags;
return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits);
}
static u32 spi_gpio_spec_txrx_word_mode2(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
unsigned flags = spi->master->flags;
return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits);
}
static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
unsigned flags = spi->master->flags;
return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits);
}
/*----------------------------------------------------------------------*/
static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
{
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
unsigned long cs = spi_gpio->cs_gpios[spi->chip_select];
/* set initial clock polarity */
if (is_active)
setsck(spi, spi->mode & SPI_CPOL);
if (cs != SPI_GPIO_NO_CHIPSELECT) {
/* SPI is normally active-low */
gpio_set_value_cansleep(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);
}
}
static int spi_gpio_setup(struct spi_device *spi)
{
unsigned long cs;
int status = 0;
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
struct device_node *np = spi->master->dev.of_node;
if (np) {
/*
* In DT environments, the CS GPIOs have already been
* initialized from the "cs-gpios" property of the node.
*/
cs = spi_gpio->cs_gpios[spi->chip_select];
} else {
/*
* ... otherwise, take it from spi->controller_data
*/
cs = (uintptr_t) spi->controller_data;
}
if (!spi->controller_state) {
if (cs != SPI_GPIO_NO_CHIPSELECT) {
status = gpio_request(cs, dev_name(&spi->dev));
if (status)
return status;
status = gpio_direction_output(cs,
!(spi->mode & SPI_CS_HIGH));
}
}
if (!status) {
/* in case it was initialized from static board data */
spi_gpio->cs_gpios[spi->chip_select] = cs;
status = spi_bitbang_setup(spi);
}
if (status) {
if (!spi->controller_state && cs != SPI_GPIO_NO_CHIPSELECT)
gpio_free(cs);
}
return status;
}
static void spi_gpio_cleanup(struct spi_device *spi)
{
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
unsigned long cs = spi_gpio->cs_gpios[spi->chip_select];
if (cs != SPI_GPIO_NO_CHIPSELECT)
gpio_free(cs);
spi_bitbang_cleanup(spi);
}
static int spi_gpio_alloc(unsigned pin, const char *label, bool is_in)
{
int value;
value = gpio_request(pin, label);
if (value == 0) {
if (is_in)
value = gpio_direction_input(pin);
else
value = gpio_direction_output(pin, 0);
}
return value;
}
static int spi_gpio_request(struct spi_gpio_platform_data *pdata,
const char *label, u16 *res_flags)
{
int value;
/* NOTE: SPI_*_GPIO symbols may reference "pdata" */
if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI) {
value = spi_gpio_alloc(SPI_MOSI_GPIO, label, false);
if (value)
goto done;
} else {
/* HW configuration without MOSI pin */
*res_flags |= SPI_MASTER_NO_TX;
}
if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO) {
value = spi_gpio_alloc(SPI_MISO_GPIO, label, true);
if (value)
goto free_mosi;
} else {
/* HW configuration without MISO pin */
*res_flags |= SPI_MASTER_NO_RX;
}
value = spi_gpio_alloc(SPI_SCK_GPIO, label, false);
if (value)
goto free_miso;
goto done;
free_miso:
if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
gpio_free(SPI_MISO_GPIO);
free_mosi:
if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
gpio_free(SPI_MOSI_GPIO);
done:
return value;
}
#ifdef CONFIG_OF
static const struct of_device_id spi_gpio_dt_ids[] = {
{ .compatible = "spi-gpio" },
{}
};
MODULE_DEVICE_TABLE(of, spi_gpio_dt_ids);
static int spi_gpio_probe_dt(struct platform_device *pdev)
{
int ret;
u32 tmp;
struct spi_gpio_platform_data *pdata;
struct device_node *np = pdev->dev.of_node;
const struct of_device_id *of_id =
of_match_device(spi_gpio_dt_ids, &pdev->dev);
if (!of_id)
return 0;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
ret = of_get_named_gpio(np, "gpio-sck", 0);
if (ret < 0) {
dev_err(&pdev->dev, "gpio-sck property not found\n");
goto error_free;
}
pdata->sck = ret;
ret = of_get_named_gpio(np, "gpio-miso", 0);
if (ret < 0) {
dev_info(&pdev->dev, "gpio-miso property not found, switching to no-rx mode\n");
pdata->miso = SPI_GPIO_NO_MISO;
} else
pdata->miso = ret;
ret = of_get_named_gpio(np, "gpio-mosi", 0);
if (ret < 0) {
dev_info(&pdev->dev, "gpio-mosi property not found, switching to no-tx mode\n");
pdata->mosi = SPI_GPIO_NO_MOSI;
} else
pdata->mosi = ret;
ret = of_property_read_u32(np, "num-chipselects", &tmp);
if (ret < 0) {
dev_err(&pdev->dev, "num-chipselects property not found\n");
goto error_free;
}
pdata->num_chipselect = tmp;
pdev->dev.platform_data = pdata;
return 1;
error_free:
devm_kfree(&pdev->dev, pdata);
return ret;
}
#else
static inline int spi_gpio_probe_dt(struct platform_device *pdev)
{
return 0;
}
#endif
static int spi_gpio_probe(struct platform_device *pdev)
{
int status;
struct spi_master *master;
struct spi_gpio *spi_gpio;
struct spi_gpio_platform_data *pdata;
u16 master_flags = 0;
bool use_of = 0;
int num_devices;
status = spi_gpio_probe_dt(pdev);
if (status < 0)
return status;
if (status > 0)
use_of = 1;
pdata = dev_get_platdata(&pdev->dev);
#ifdef GENERIC_BITBANG
if (!pdata || (!use_of && !pdata->num_chipselect))
return -ENODEV;
#endif
if (use_of && !SPI_N_CHIPSEL)
num_devices = 1;
else
num_devices = SPI_N_CHIPSEL;
status = spi_gpio_request(pdata, dev_name(&pdev->dev), &master_flags);
if (status < 0)
return status;
master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio) +
(sizeof(unsigned long) * num_devices));
if (!master) {
status = -ENOMEM;
goto gpio_free;
}
spi_gpio = spi_master_get_devdata(master);
platform_set_drvdata(pdev, spi_gpio);
spi_gpio->pdev = pdev;
if (pdata)
spi_gpio->pdata = *pdata;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
master->flags = master_flags;
master->bus_num = pdev->id;
master->num_chipselect = num_devices;
master->setup = spi_gpio_setup;
master->cleanup = spi_gpio_cleanup;
#ifdef CONFIG_OF
master->dev.of_node = pdev->dev.of_node;
if (use_of) {
int i;
struct device_node *np = pdev->dev.of_node;
/*
* In DT environments, take the CS GPIO from the "cs-gpios"
* property of the node.
*/
if (!SPI_N_CHIPSEL)
spi_gpio->cs_gpios[0] = SPI_GPIO_NO_CHIPSELECT;
else
for (i = 0; i < SPI_N_CHIPSEL; i++) {
status = of_get_named_gpio(np, "cs-gpios", i);
if (status < 0) {
dev_err(&pdev->dev,
"invalid cs-gpios property\n");
goto gpio_free;
}
spi_gpio->cs_gpios[i] = status;
}
}
#endif
spi_gpio->bitbang.master = master;
spi_gpio->bitbang.chipselect = spi_gpio_chipselect;
if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) {
spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0;
spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1;
spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2;
spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_word_mode3;
} else {
spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_spec_txrx_word_mode0;
spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_spec_txrx_word_mode1;
spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_spec_txrx_word_mode2;
spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_spec_txrx_word_mode3;
}
spi_gpio->bitbang.setup_transfer = spi_bitbang_setup_transfer;
spi_gpio->bitbang.flags = SPI_CS_HIGH;
status = spi_bitbang_start(&spi_gpio->bitbang);
if (status < 0) {
gpio_free:
if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
gpio_free(SPI_MISO_GPIO);
if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
gpio_free(SPI_MOSI_GPIO);
gpio_free(SPI_SCK_GPIO);
spi_master_put(master);
}
return status;
}
static int spi_gpio_remove(struct platform_device *pdev)
{
struct spi_gpio *spi_gpio;
struct spi_gpio_platform_data *pdata;
spi_gpio = platform_get_drvdata(pdev);
pdata = dev_get_platdata(&pdev->dev);
/* stop() unregisters child devices too */
spi_bitbang_stop(&spi_gpio->bitbang);
if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
gpio_free(SPI_MISO_GPIO);
if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
gpio_free(SPI_MOSI_GPIO);
gpio_free(SPI_SCK_GPIO);
spi_master_put(spi_gpio->bitbang.master);
return 0;
}
MODULE_ALIAS("platform:" DRIVER_NAME);
static struct platform_driver spi_gpio_driver = {
.driver = {
.name = DRIVER_NAME,
.of_match_table = of_match_ptr(spi_gpio_dt_ids),
},
.probe = spi_gpio_probe,
.remove = spi_gpio_remove,
};
module_platform_driver(spi_gpio_driver);
MODULE_DESCRIPTION("SPI master driver using generic bitbanged GPIO ");
MODULE_AUTHOR("David Brownell");
MODULE_LICENSE("GPL");

View File

@ -1,543 +0,0 @@
/*
* Copyright (C) 2004 IBM Corporation
* Copyright (C) 2015 Intel Corporation
*
* Authors:
* Leendert van Doorn <leendert@watson.ibm.com>
* Dave Safford <safford@watson.ibm.com>
* Reiner Sailer <sailer@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
* Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org
*
* 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, version 2 of the
* License.
*
*/
#ifndef __TPM_H__
#define __TPM_H__
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/tpm.h>
#include <linux/acpi.h>
#include <linux/cdev.h>
#include <linux/highmem.h>
enum tpm_const {
TPM_MINOR = 224, /* officially assigned */
TPM_BUFSIZE = 4096,
TPM_NUM_DEVICES = 65536,
TPM_RETRY = 50, /* 5 seconds */
};
enum tpm_timeout {
TPM_TIMEOUT = 5, /* msecs */
TPM_TIMEOUT_RETRY = 100 /* msecs */
};
/* TPM addresses */
enum tpm_addr {
TPM_SUPERIO_ADDR = 0x2E,
TPM_ADDR = 0x4E,
};
/* Indexes the duration array */
enum tpm_duration {
TPM_SHORT = 0,
TPM_MEDIUM = 1,
TPM_LONG = 2,
TPM_UNDEFINED,
};
#define TPM_WARN_RETRY 0x800
#define TPM_WARN_DOING_SELFTEST 0x802
#define TPM_ERR_DEACTIVATED 0x6
#define TPM_ERR_DISABLED 0x7
#define TPM_ERR_INVALID_POSTINIT 38
#define TPM_HEADER_SIZE 10
enum tpm2_const {
TPM2_PLATFORM_PCR = 24,
TPM2_PCR_SELECT_MIN = ((TPM2_PLATFORM_PCR + 7) / 8),
TPM2_TIMEOUT_A = 750,
TPM2_TIMEOUT_B = 2000,
TPM2_TIMEOUT_C = 200,
TPM2_TIMEOUT_D = 30,
TPM2_DURATION_SHORT = 20,
TPM2_DURATION_MEDIUM = 750,
TPM2_DURATION_LONG = 2000,
};
enum tpm2_structures {
TPM2_ST_NO_SESSIONS = 0x8001,
TPM2_ST_SESSIONS = 0x8002,
};
enum tpm2_return_codes {
TPM2_RC_HASH = 0x0083, /* RC_FMT1 */
TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */
TPM2_RC_DISABLED = 0x0120,
TPM2_RC_TESTING = 0x090A, /* RC_WARN */
};
enum tpm2_algorithms {
TPM2_ALG_SHA1 = 0x0004,
TPM2_ALG_KEYEDHASH = 0x0008,
TPM2_ALG_SHA256 = 0x000B,
TPM2_ALG_SHA384 = 0x000C,
TPM2_ALG_SHA512 = 0x000D,
TPM2_ALG_NULL = 0x0010,
TPM2_ALG_SM3_256 = 0x0012,
};
enum tpm2_command_codes {
TPM2_CC_FIRST = 0x011F,
TPM2_CC_SELF_TEST = 0x0143,
TPM2_CC_STARTUP = 0x0144,
TPM2_CC_SHUTDOWN = 0x0145,
TPM2_CC_CREATE = 0x0153,
TPM2_CC_LOAD = 0x0157,
TPM2_CC_UNSEAL = 0x015E,
TPM2_CC_FLUSH_CONTEXT = 0x0165,
TPM2_CC_GET_CAPABILITY = 0x017A,
TPM2_CC_GET_RANDOM = 0x017B,
TPM2_CC_PCR_READ = 0x017E,
TPM2_CC_PCR_EXTEND = 0x0182,
TPM2_CC_LAST = 0x018F,
};
enum tpm2_permanent_handles {
TPM2_RS_PW = 0x40000009,
};
enum tpm2_capabilities {
TPM2_CAP_TPM_PROPERTIES = 6,
};
enum tpm2_startup_types {
TPM2_SU_CLEAR = 0x0000,
TPM2_SU_STATE = 0x0001,
};
#define TPM_VID_INTEL 0x8086
#define TPM_VID_WINBOND 0x1050
#define TPM_VID_STM 0x104A
#define TPM_PPI_VERSION_LEN 3
enum tpm_chip_flags {
TPM_CHIP_FLAG_REGISTERED = BIT(0),
TPM_CHIP_FLAG_TPM2 = BIT(1),
TPM_CHIP_FLAG_IRQ = BIT(2),
TPM_CHIP_FLAG_VIRTUAL = BIT(3),
TPM_CHIP_FLAG_ALWAYS_POWERED = BIT(5),
};
struct tpm_chip {
struct device dev;
struct cdev cdev;
/* A driver callback under ops cannot be run unless ops_sem is held
* (sometimes implicitly, eg for the sysfs code). ops becomes null
* when the driver is unregistered, see tpm_try_get_ops.
*/
struct rw_semaphore ops_sem;
const struct tpm_class_ops *ops;
unsigned int flags;
int dev_num; /* /dev/tpm# */
unsigned long is_open; /* only one allowed */
struct mutex tpm_mutex; /* tpm is processing */
unsigned long timeout_a; /* jiffies */
unsigned long timeout_b; /* jiffies */
unsigned long timeout_c; /* jiffies */
unsigned long timeout_d; /* jiffies */
bool timeout_adjusted;
unsigned long duration[3]; /* jiffies */
bool duration_adjusted;
struct dentry **bios_dir;
const struct attribute_group *groups[3];
unsigned int groups_cnt;
#ifdef CONFIG_ACPI
acpi_handle acpi_dev_handle;
char ppi_version[TPM_PPI_VERSION_LEN + 1];
#endif /* CONFIG_ACPI */
};
#define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
static inline int tpm_read_index(int base, int index)
{
outb(index, base);
return inb(base+1) & 0xFF;
}
static inline void tpm_write_index(int base, int index, int value)
{
outb(index, base);
outb(value & 0xFF, base+1);
}
struct tpm_input_header {
__be16 tag;
__be32 length;
__be32 ordinal;
} __packed;
struct tpm_output_header {
__be16 tag;
__be32 length;
__be32 return_code;
} __packed;
#define TPM_TAG_RQU_COMMAND cpu_to_be16(193)
struct stclear_flags_t {
__be16 tag;
u8 deactivated;
u8 disableForceClear;
u8 physicalPresence;
u8 physicalPresenceLock;
u8 bGlobalLock;
} __packed;
struct tpm_version_t {
u8 Major;
u8 Minor;
u8 revMajor;
u8 revMinor;
} __packed;
struct tpm_version_1_2_t {
__be16 tag;
u8 Major;
u8 Minor;
u8 revMajor;
u8 revMinor;
} __packed;
struct timeout_t {
__be32 a;
__be32 b;
__be32 c;
__be32 d;
} __packed;
struct duration_t {
__be32 tpm_short;
__be32 tpm_medium;
__be32 tpm_long;
} __packed;
struct permanent_flags_t {
__be16 tag;
u8 disable;
u8 ownership;
u8 deactivated;
u8 readPubek;
u8 disableOwnerClear;
u8 allowMaintenance;
u8 physicalPresenceLifetimeLock;
u8 physicalPresenceHWEnable;
u8 physicalPresenceCMDEnable;
u8 CEKPUsed;
u8 TPMpost;
u8 TPMpostLock;
u8 FIPS;
u8 operator;
u8 enableRevokeEK;
u8 nvLocked;
u8 readSRKPub;
u8 tpmEstablished;
u8 maintenanceDone;
u8 disableFullDALogicInfo;
} __packed;
typedef union {
struct permanent_flags_t perm_flags;
struct stclear_flags_t stclear_flags;
bool owned;
__be32 num_pcrs;
struct tpm_version_t tpm_version;
struct tpm_version_1_2_t tpm_version_1_2;
__be32 manufacturer_id;
struct timeout_t timeout;
struct duration_t duration;
} cap_t;
enum tpm_capabilities {
TPM_CAP_FLAG = cpu_to_be32(4),
TPM_CAP_PROP = cpu_to_be32(5),
CAP_VERSION_1_1 = cpu_to_be32(0x06),
CAP_VERSION_1_2 = cpu_to_be32(0x1A)
};
enum tpm_sub_capabilities {
TPM_CAP_PROP_PCR = cpu_to_be32(0x101),
TPM_CAP_PROP_MANUFACTURER = cpu_to_be32(0x103),
TPM_CAP_FLAG_PERM = cpu_to_be32(0x108),
TPM_CAP_FLAG_VOL = cpu_to_be32(0x109),
TPM_CAP_PROP_OWNER = cpu_to_be32(0x111),
TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115),
TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120),
};
struct tpm_getcap_params_in {
__be32 cap;
__be32 subcap_size;
__be32 subcap;
} __packed;
struct tpm_getcap_params_out {
__be32 cap_size;
cap_t cap;
} __packed;
struct tpm_readpubek_params_out {
u8 algorithm[4];
u8 encscheme[2];
u8 sigscheme[2];
__be32 paramsize;
u8 parameters[12]; /*assuming RSA*/
__be32 keysize;
u8 modulus[256];
u8 checksum[20];
} __packed;
typedef union {
struct tpm_input_header in;
struct tpm_output_header out;
} tpm_cmd_header;
struct tpm_pcrread_out {
u8 pcr_result[TPM_DIGEST_SIZE];
} __packed;
struct tpm_pcrread_in {
__be32 pcr_idx;
} __packed;
struct tpm_pcrextend_in {
__be32 pcr_idx;
u8 hash[TPM_DIGEST_SIZE];
} __packed;
/* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
* bytes, but 128 is still a relatively large number of random bytes and
* anything much bigger causes users of struct tpm_cmd_t to start getting
* compiler warnings about stack frame size. */
#define TPM_MAX_RNG_DATA 128
struct tpm_getrandom_out {
__be32 rng_data_len;
u8 rng_data[TPM_MAX_RNG_DATA];
} __packed;
struct tpm_getrandom_in {
__be32 num_bytes;
} __packed;
struct tpm_startup_in {
__be16 startup_type;
} __packed;
typedef union {
struct tpm_getcap_params_out getcap_out;
struct tpm_readpubek_params_out readpubek_out;
u8 readpubek_out_buffer[sizeof(struct tpm_readpubek_params_out)];
struct tpm_getcap_params_in getcap_in;
struct tpm_pcrread_in pcrread_in;
struct tpm_pcrread_out pcrread_out;
struct tpm_pcrextend_in pcrextend_in;
struct tpm_getrandom_in getrandom_in;
struct tpm_getrandom_out getrandom_out;
struct tpm_startup_in startup_in;
} tpm_cmd_params;
struct tpm_cmd_t {
tpm_cmd_header header;
tpm_cmd_params params;
} __packed;
/* A string buffer type for constructing TPM commands. This is based on the
* ideas of string buffer code in security/keys/trusted.h but is heap based
* in order to keep the stack usage minimal.
*/
enum tpm_buf_flags {
TPM_BUF_OVERFLOW = BIT(0),
};
struct tpm_buf {
struct page *data_page;
unsigned int flags;
u8 *data;
};
static inline int tpm_buf_init(struct tpm_buf *buf, u16 tag, u32 ordinal)
{
struct tpm_input_header *head;
buf->data_page = alloc_page(GFP_HIGHUSER);
if (!buf->data_page)
return -ENOMEM;
buf->flags = 0;
buf->data = kmap(buf->data_page);
head = (struct tpm_input_header *) buf->data;
head->tag = cpu_to_be16(tag);
head->length = cpu_to_be32(sizeof(*head));
head->ordinal = cpu_to_be32(ordinal);
return 0;
}
static inline void tpm_buf_destroy(struct tpm_buf *buf)
{
kunmap(buf->data_page);
__free_page(buf->data_page);
}
static inline u32 tpm_buf_length(struct tpm_buf *buf)
{
struct tpm_input_header *head = (struct tpm_input_header *) buf->data;
return be32_to_cpu(head->length);
}
static inline u16 tpm_buf_tag(struct tpm_buf *buf)
{
struct tpm_input_header *head = (struct tpm_input_header *) buf->data;
return be16_to_cpu(head->tag);
}
static inline void tpm_buf_append(struct tpm_buf *buf,
const unsigned char *new_data,
unsigned int new_len)
{
struct tpm_input_header *head = (struct tpm_input_header *) buf->data;
u32 len = tpm_buf_length(buf);
/* Return silently if overflow has already happened. */
if (buf->flags & TPM_BUF_OVERFLOW)
return;
if ((len + new_len) > PAGE_SIZE) {
WARN(1, "tpm_buf: overflow\n");
buf->flags |= TPM_BUF_OVERFLOW;
return;
}
memcpy(&buf->data[len], new_data, new_len);
head->length = cpu_to_be32(len + new_len);
}
static inline void tpm_buf_append_u8(struct tpm_buf *buf, const u8 value)
{
tpm_buf_append(buf, &value, 1);
}
static inline void tpm_buf_append_u16(struct tpm_buf *buf, const u16 value)
{
__be16 value2 = cpu_to_be16(value);
tpm_buf_append(buf, (u8 *) &value2, 2);
}
static inline void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value)
{
__be32 value2 = cpu_to_be32(value);
tpm_buf_append(buf, (u8 *) &value2, 4);
}
extern struct class *tpm_class;
extern dev_t tpm_devt;
extern const struct file_operations tpm_fops;
extern struct idr dev_nums_idr;
enum tpm_transmit_flags {
TPM_TRANSMIT_UNLOCKED = BIT(0),
};
ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
unsigned int flags);
ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *cmd, int len,
unsigned int flags, const char *desc);
ssize_t tpm_getcap(struct tpm_chip *chip, __be32 subcap_id, cap_t *cap,
const char *desc);
int tpm_get_timeouts(struct tpm_chip *);
int tpm1_auto_startup(struct tpm_chip *chip);
int tpm_do_selftest(struct tpm_chip *chip);
unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
int tpm_pm_suspend(struct device *dev);
int tpm_pm_resume(struct device *dev);
int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
wait_queue_head_t *queue, bool check_cancel);
struct tpm_chip *tpm_chip_find_get(int chip_num);
__must_check int tpm_try_get_ops(struct tpm_chip *chip);
void tpm_put_ops(struct tpm_chip *chip);
struct tpm_chip *tpm_chip_alloc(struct device *dev,
const struct tpm_class_ops *ops);
struct tpm_chip *tpmm_chip_alloc(struct device *pdev,
const struct tpm_class_ops *ops);
int tpm_chip_register(struct tpm_chip *chip);
void tpm_chip_unregister(struct tpm_chip *chip);
void tpm_sysfs_add_device(struct tpm_chip *chip);
int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
#ifdef CONFIG_ACPI
extern void tpm_add_ppi(struct tpm_chip *chip);
#else
static inline void tpm_add_ppi(struct tpm_chip *chip)
{
}
#endif
static inline inline u32 tpm2_rc_value(u32 rc)
{
return (rc & BIT(7)) ? rc & 0xff : rc;
}
int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash);
int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max);
int tpm2_seal_trusted(struct tpm_chip *chip,
struct trusted_key_payload *payload,
struct trusted_key_options *options);
int tpm2_unseal_trusted(struct tpm_chip *chip,
struct trusted_key_payload *payload,
struct trusted_key_options *options);
ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id,
u32 *value, const char *desc);
int tpm2_auto_startup(struct tpm_chip *chip);
void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
int tpm2_probe(struct tpm_chip *chip);
#endif

View File

@ -1,855 +0,0 @@
/*
* Copyright (C) 2005, 2006 IBM Corporation
* Copyright (C) 2014, 2015 Intel Corporation
*
* Authors:
* Leendert van Doorn <leendert@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
* Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org
*
* This device driver implements the TPM interface as defined in
* the TCG TPM Interface Spec version 1.2, revision 1.0.
*
* 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, version 2 of the
* License.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pnp.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/acpi.h>
#include <linux/freezer.h>
#include "tpm.h"
#include "tpm_tis_core.h"
/* Before we attempt to access the TPM we must see that the valid bit is set.
* The specification says that this bit is 0 at reset and remains 0 until the
* 'TPM has gone through its self test and initialization and has established
* correct values in the other bits.'
*/
static int wait_startup(struct tpm_chip *chip, int l)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
unsigned long stop = jiffies + chip->timeout_a;
do {
int rc;
u8 access;
rc = tpm_tis_read8(priv, TPM_ACCESS(l), &access);
if (rc < 0)
return rc;
if (access & TPM_ACCESS_VALID)
return 0;
msleep(TPM_TIMEOUT);
} while (time_before(jiffies, stop));
return -1;
}
static int check_locality(struct tpm_chip *chip, int l)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
int rc;
u8 access;
rc = tpm_tis_read8(priv, TPM_ACCESS(l), &access);
if (rc < 0)
return rc;
if ((access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
(TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
return priv->locality = l;
return -1;
}
static void release_locality(struct tpm_chip *chip, int l, int force)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
int rc;
u8 access;
rc = tpm_tis_read8(priv, TPM_ACCESS(l), &access);
if (rc < 0)
return;
if (force || (access &
(TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
(TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
}
static int request_locality(struct tpm_chip *chip, int l)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
unsigned long stop, timeout;
long rc;
if (check_locality(chip, l) >= 0)
return l;
rc = tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_REQUEST_USE);
if (rc < 0)
return rc;
stop = jiffies + chip->timeout_a;
if (chip->flags & TPM_CHIP_FLAG_IRQ) {
again:
timeout = stop - jiffies;
if ((long)timeout <= 0)
return -1;
rc = wait_event_interruptible_timeout(priv->int_queue,
(check_locality
(chip, l) >= 0),
timeout);
if (rc > 0)
return l;
if (rc == -ERESTARTSYS && freezing(current)) {
clear_thread_flag(TIF_SIGPENDING);
goto again;
}
} else {
/* wait for burstcount */
do {
if (check_locality(chip, l) >= 0)
return l;
msleep(TPM_TIMEOUT);
} while (time_before(jiffies, stop));
}
return -1;
}
static u8 tpm_tis_status(struct tpm_chip *chip)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
int rc;
u8 status;
rc = tpm_tis_read8(priv, TPM_STS(priv->locality), &status);
if (rc < 0)
return 0;
return status;
}
static void tpm_tis_ready(struct tpm_chip *chip)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
/* this causes the current command to be aborted */
tpm_tis_write8(priv, TPM_STS(priv->locality), TPM_STS_COMMAND_READY);
}
static int get_burstcount(struct tpm_chip *chip)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
unsigned long stop;
int burstcnt, rc;
u32 value;
/* wait for burstcount */
if (chip->flags & TPM_CHIP_FLAG_TPM2)
stop = jiffies + chip->timeout_a;
else
stop = jiffies + chip->timeout_d;
do {
rc = tpm_tis_read32(priv, TPM_STS(priv->locality), &value);
if (rc < 0)
return rc;
burstcnt = (value >> 8) & 0xFFFF;
if (burstcnt)
return burstcnt;
msleep(TPM_TIMEOUT);
} while (time_before(jiffies, stop));
return -EBUSY;
}
static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
int size = 0, burstcnt, rc;
while (size < count &&
wait_for_tpm_stat(chip,
TPM_STS_DATA_AVAIL | TPM_STS_VALID,
chip->timeout_c,
&priv->read_queue, true) == 0) {
burstcnt = get_burstcount(chip);
if (burstcnt < 0) {
dev_err(&chip->dev, "Unable to read burstcount\n");
return burstcnt;
}
burstcnt = min_t(int, burstcnt, count - size);
rc = tpm_tis_read_bytes(priv, TPM_DATA_FIFO(priv->locality),
burstcnt, buf + size);
if (rc < 0)
return rc;
size += burstcnt;
}
return size;
}
static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
int size = 0;
int status;
u32 expected;
if (count < TPM_HEADER_SIZE) {
size = -EIO;
goto out;
}
size = recv_data(chip, buf, TPM_HEADER_SIZE);
/* read first 10 bytes, including tag, paramsize, and result */
if (size < TPM_HEADER_SIZE) {
dev_err(&chip->dev, "Unable to read header\n");
goto out;
}
expected = be32_to_cpu(*(__be32 *) (buf + 2));
if (expected > count || expected < TPM_HEADER_SIZE) {
size = -EIO;
goto out;
}
size += recv_data(chip, &buf[TPM_HEADER_SIZE],
expected - TPM_HEADER_SIZE);
if (size < expected) {
dev_err(&chip->dev, "Unable to read remainder of result\n");
size = -ETIME;
goto out;
}
wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
&priv->int_queue, false);
status = tpm_tis_status(chip);
if (status & TPM_STS_DATA_AVAIL) { /* retry? */
dev_err(&chip->dev, "Error left over data\n");
size = -EIO;
goto out;
}
out:
tpm_tis_ready(chip);
release_locality(chip, priv->locality, 0);
return size;
}
/*
* If interrupts are used (signaled by an irq set in the vendor structure)
* tpm.c can skip polling for the data to be available as the interrupt is
* waited for here
*/
static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
int rc, status, burstcnt;
size_t count = 0;
bool itpm = priv->flags & TPM_TIS_ITPM_POSSIBLE;
if (request_locality(chip, 0) < 0)
return -EBUSY;
status = tpm_tis_status(chip);
if ((status & TPM_STS_COMMAND_READY) == 0) {
tpm_tis_ready(chip);
if (wait_for_tpm_stat
(chip, TPM_STS_COMMAND_READY, chip->timeout_b,
&priv->int_queue, false) < 0) {
rc = -ETIME;
goto out_err;
}
}
while (count < len - 1) {
burstcnt = get_burstcount(chip);
if (burstcnt < 0) {
dev_err(&chip->dev, "Unable to read burstcount\n");
rc = burstcnt;
goto out_err;
}
burstcnt = min_t(int, burstcnt, len - count - 1);
rc = tpm_tis_write_bytes(priv, TPM_DATA_FIFO(priv->locality),
burstcnt, buf + count);
if (rc < 0)
goto out_err;
count += burstcnt;
wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
&priv->int_queue, false);
status = tpm_tis_status(chip);
if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) {
rc = -EIO;
goto out_err;
}
}
/* write last byte */
rc = tpm_tis_write8(priv, TPM_DATA_FIFO(priv->locality), buf[count]);
if (rc < 0)
goto out_err;
wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
&priv->int_queue, false);
status = tpm_tis_status(chip);
if (!itpm && (status & TPM_STS_DATA_EXPECT) != 0) {
rc = -EIO;
goto out_err;
}
return 0;
out_err:
tpm_tis_ready(chip);
release_locality(chip, priv->locality, 0);
return rc;
}
static void disable_interrupts(struct tpm_chip *chip)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
u32 intmask;
int rc;
rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
if (rc < 0)
intmask = 0;
intmask &= ~TPM_GLOBAL_INT_ENABLE;
rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
devm_free_irq(chip->dev.parent, priv->irq, chip);
priv->irq = 0;
chip->flags &= ~TPM_CHIP_FLAG_IRQ;
}
/*
* If interrupts are used (signaled by an irq set in the vendor structure)
* tpm.c can skip polling for the data to be available as the interrupt is
* waited for here
*/
static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
int rc;
u32 ordinal;
unsigned long dur;
rc = tpm_tis_send_data(chip, buf, len);
if (rc < 0)
return rc;
/* go and do it */
rc = tpm_tis_write8(priv, TPM_STS(priv->locality), TPM_STS_GO);
if (rc < 0)
goto out_err;
if (chip->flags & TPM_CHIP_FLAG_IRQ) {
ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
if (chip->flags & TPM_CHIP_FLAG_TPM2)
dur = tpm2_calc_ordinal_duration(chip, ordinal);
else
dur = tpm_calc_ordinal_duration(chip, ordinal);
if (wait_for_tpm_stat
(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID, dur,
&priv->read_queue, false) < 0) {
rc = -ETIME;
goto out_err;
}
}
return len;
out_err:
tpm_tis_ready(chip);
release_locality(chip, priv->locality, 0);
return rc;
}
static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
{
int rc, irq;
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
if (!(chip->flags & TPM_CHIP_FLAG_IRQ) || priv->irq_tested)
return tpm_tis_send_main(chip, buf, len);
/* Verify receipt of the expected IRQ */
irq = priv->irq;
priv->irq = 0;
chip->flags &= ~TPM_CHIP_FLAG_IRQ;
rc = tpm_tis_send_main(chip, buf, len);
priv->irq = irq;
chip->flags |= TPM_CHIP_FLAG_IRQ;
if (!priv->irq_tested)
msleep(1);
if (!priv->irq_tested)
disable_interrupts(chip);
priv->irq_tested = true;
return rc;
}
struct tis_vendor_timeout_override {
u32 did_vid;
unsigned long timeout_us[4];
};
static const struct tis_vendor_timeout_override vendor_timeout_overrides[] = {
/* Atmel 3204 */
{ 0x32041114, { (TIS_SHORT_TIMEOUT*1000), (TIS_LONG_TIMEOUT*1000),
(TIS_SHORT_TIMEOUT*1000), (TIS_SHORT_TIMEOUT*1000) } },
};
static bool tpm_tis_update_timeouts(struct tpm_chip *chip,
unsigned long *timeout_cap)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
int i, rc;
u32 did_vid;
rc = tpm_tis_read32(priv, TPM_DID_VID(0), &did_vid);
if (rc < 0)
return rc;
for (i = 0; i != ARRAY_SIZE(vendor_timeout_overrides); i++) {
if (vendor_timeout_overrides[i].did_vid != did_vid)
continue;
memcpy(timeout_cap, vendor_timeout_overrides[i].timeout_us,
sizeof(vendor_timeout_overrides[i].timeout_us));
return true;
}
return false;
}
/*
* Early probing for iTPM with STS_DATA_EXPECT flaw.
* Try sending command without itpm flag set and if that
* fails, repeat with itpm flag set.
*/
static int probe_itpm(struct tpm_chip *chip)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
int rc = 0;
u8 cmd_getticks[] = {
0x00, 0xc1, 0x00, 0x00, 0x00, 0x0a,
0x00, 0x00, 0x00, 0xf1
};
size_t len = sizeof(cmd_getticks);
u16 vendor;
rc = tpm_tis_read16(priv, TPM_DID_VID(0), &vendor);
if (rc < 0)
return rc;
/* probe only iTPMS */
if (vendor != TPM_VID_INTEL)
return 0;
rc = tpm_tis_send_data(chip, cmd_getticks, len);
if (rc == 0)
goto out;
tpm_tis_ready(chip);
release_locality(chip, priv->locality, 0);
rc = tpm_tis_send_data(chip, cmd_getticks, len);
if (rc == 0) {
dev_info(&chip->dev, "Detected an iTPM.\n");
rc = 1;
} else
rc = -EFAULT;
out:
tpm_tis_ready(chip);
release_locality(chip, priv->locality, 0);
return rc;
}
static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
switch (priv->manufacturer_id) {
case TPM_VID_WINBOND:
return ((status == TPM_STS_VALID) ||
(status == (TPM_STS_VALID | TPM_STS_COMMAND_READY)));
case TPM_VID_STM:
return (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY));
default:
return (status == TPM_STS_COMMAND_READY);
}
}
static irqreturn_t tis_int_handler(int dummy, void *dev_id)
{
struct tpm_chip *chip = dev_id;
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
u32 interrupt;
int i, rc;
rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &interrupt);
if (rc < 0)
return IRQ_NONE;
if (interrupt == 0)
return IRQ_NONE;
priv->irq_tested = true;
if (interrupt & TPM_INTF_DATA_AVAIL_INT)
wake_up_interruptible(&priv->read_queue);
if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
for (i = 0; i < 5; i++)
if (check_locality(chip, i) >= 0)
break;
if (interrupt &
(TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
TPM_INTF_CMD_READY_INT))
wake_up_interruptible(&priv->int_queue);
/* Clear interrupts handled with TPM_EOI */
rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), interrupt);
if (rc < 0)
return IRQ_NONE;
tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &interrupt);
return IRQ_HANDLED;
}
static int tpm_tis_gen_interrupt(struct tpm_chip *chip)
{
const char *desc = "attempting to generate an interrupt";
u32 cap2;
cap_t cap;
if (chip->flags & TPM_CHIP_FLAG_TPM2)
return tpm2_get_tpm_pt(chip, 0x100, &cap2, desc);
else
return tpm_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc);
}
/* Register the IRQ and issue a command that will cause an interrupt. If an
* irq is seen then leave the chip setup for IRQ operation, otherwise reverse
* everything and leave in polling mode. Returns 0 on success.
*/
static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
int flags, int irq)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
u8 original_int_vec;
int rc;
u32 int_status;
if (devm_request_irq(chip->dev.parent, irq, tis_int_handler, flags,
dev_name(&chip->dev), chip) != 0) {
dev_info(&chip->dev, "Unable to request irq: %d for probe\n",
irq);
return -1;
}
priv->irq = irq;
rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality),
&original_int_vec);
if (rc < 0)
return rc;
rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), irq);
if (rc < 0)
return rc;
rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status);
if (rc < 0)
return rc;
/* Clear all existing */
rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status);
if (rc < 0)
return rc;
/* Turn on */
rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality),
intmask | TPM_GLOBAL_INT_ENABLE);
if (rc < 0)
return rc;
priv->irq_tested = false;
/* Generate an interrupt by having the core call through to
* tpm_tis_send
*/
rc = tpm_tis_gen_interrupt(chip);
if (rc < 0)
return rc;
/* tpm_tis_send will either confirm the interrupt is working or it
* will call disable_irq which undoes all of the above.
*/
if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
rc = tpm_tis_write8(priv, original_int_vec,
TPM_INT_VECTOR(priv->locality));
if (rc < 0)
return rc;
return 1;
}
return 0;
}
/* Try to find the IRQ the TPM is using. This is for legacy x86 systems that
* do not have ACPI/etc. We typically expect the interrupt to be declared if
* present.
*/
static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
u8 original_int_vec;
int i, rc;
rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality),
&original_int_vec);
if (rc < 0)
return;
if (!original_int_vec) {
if (IS_ENABLED(CONFIG_X86))
for (i = 3; i <= 15; i++)
if (!tpm_tis_probe_irq_single(chip, intmask, 0,
i))
return;
} else if (!tpm_tis_probe_irq_single(chip, intmask, 0,
original_int_vec))
return;
}
void tpm_tis_remove(struct tpm_chip *chip)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
u32 reg = TPM_INT_ENABLE(priv->locality);
u32 interrupt;
int rc;
rc = tpm_tis_read32(priv, reg, &interrupt);
if (rc < 0)
interrupt = 0;
tpm_tis_write32(priv, reg, ~TPM_GLOBAL_INT_ENABLE & interrupt);
release_locality(chip, priv->locality, 1);
}
EXPORT_SYMBOL_GPL(tpm_tis_remove);
static const struct tpm_class_ops tpm_tis = {
.flags = TPM_OPS_AUTO_STARTUP,
.status = tpm_tis_status,
.recv = tpm_tis_recv,
.send = tpm_tis_send,
.cancel = tpm_tis_ready,
.update_timeouts = tpm_tis_update_timeouts,
.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
.req_canceled = tpm_tis_req_canceled,
};
int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
const struct tpm_tis_phy_ops *phy_ops,
acpi_handle acpi_dev_handle)
{
u32 vendor, intfcaps, intmask;
u8 rid;
int rc, probe;
struct tpm_chip *chip;
chip = tpmm_chip_alloc(dev, &tpm_tis);
if (IS_ERR(chip))
return PTR_ERR(chip);
#ifdef CONFIG_ACPI
chip->acpi_dev_handle = acpi_dev_handle;
#endif
/* Maximum timeouts */
chip->timeout_a = msecs_to_jiffies(TIS_TIMEOUT_A_MAX);
chip->timeout_b = msecs_to_jiffies(TIS_TIMEOUT_B_MAX);
chip->timeout_c = msecs_to_jiffies(TIS_TIMEOUT_C_MAX);
chip->timeout_d = msecs_to_jiffies(TIS_TIMEOUT_D_MAX);
priv->phy_ops = phy_ops;
dev_set_drvdata(&chip->dev, priv);
if (wait_startup(chip, 0) != 0) {
rc = -ENODEV;
goto out_err;
}
/* Take control of the TPM's interrupt hardware and shut it off */
rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
if (rc < 0)
goto out_err;
intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT;
intmask &= ~TPM_GLOBAL_INT_ENABLE;
tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
if (request_locality(chip, 0) != 0) {
rc = -ENODEV;
goto out_err;
}
rc = tpm2_probe(chip);
if (rc)
goto out_err;
rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor);
if (rc < 0)
goto out_err;
priv->manufacturer_id = vendor;
rc = tpm_tis_read8(priv, TPM_RID(0), &rid);
if (rc < 0)
goto out_err;
dev_info(dev, "%s TPM (device-id 0x%X, rev-id %d)\n",
(chip->flags & TPM_CHIP_FLAG_TPM2) ? "2.0" : "1.2",
vendor >> 16, rid);
if (!(priv->flags & TPM_TIS_ITPM_POSSIBLE)) {
probe = probe_itpm(chip);
if (probe < 0) {
rc = -ENODEV;
goto out_err;
}
if (!!probe)
priv->flags |= TPM_TIS_ITPM_POSSIBLE;
}
/* Figure out the capabilities */
rc = tpm_tis_read32(priv, TPM_INTF_CAPS(priv->locality), &intfcaps);
if (rc < 0)
goto out_err;
dev_dbg(dev, "TPM interface capabilities (0x%x):\n",
intfcaps);
if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
dev_dbg(dev, "\tBurst Count Static\n");
if (intfcaps & TPM_INTF_CMD_READY_INT)
dev_dbg(dev, "\tCommand Ready Int Support\n");
if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
dev_dbg(dev, "\tInterrupt Edge Falling\n");
if (intfcaps & TPM_INTF_INT_EDGE_RISING)
dev_dbg(dev, "\tInterrupt Edge Rising\n");
if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
dev_dbg(dev, "\tInterrupt Level Low\n");
if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
dev_dbg(dev, "\tInterrupt Level High\n");
if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
dev_dbg(dev, "\tLocality Change Int Support\n");
if (intfcaps & TPM_INTF_STS_VALID_INT)
dev_dbg(dev, "\tSts Valid Int Support\n");
if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
dev_dbg(dev, "\tData Avail Int Support\n");
/* Very early on issue a command to the TPM in polling mode to make
* sure it works. May as well use that command to set the proper
* timeouts for the driver.
*/
if (tpm_get_timeouts(chip)) {
dev_err(dev, "Could not get TPM timeouts and durations\n");
rc = -ENODEV;
goto out_err;
}
/* INTERRUPT Setup */
init_waitqueue_head(&priv->read_queue);
init_waitqueue_head(&priv->int_queue);
if (irq != -1) {
if (irq) {
tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
irq);
if (!(chip->flags & TPM_CHIP_FLAG_IRQ))
dev_err(&chip->dev, FW_BUG
"TPM interrupt not working, polling instead\n");
} else {
tpm_tis_probe_irq(chip, intmask);
}
}
return tpm_chip_register(chip);
out_err:
tpm_tis_remove(chip);
return rc;
}
EXPORT_SYMBOL_GPL(tpm_tis_core_init);
#ifdef CONFIG_PM_SLEEP
static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
u32 intmask;
int rc;
/* reenable interrupts that device may have lost or
* BIOS/firmware may have disabled
*/
rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), priv->irq);
if (rc < 0)
return;
rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
if (rc < 0)
return;
intmask |= TPM_INTF_CMD_READY_INT
| TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
| TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE;
tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
}
int tpm_tis_resume(struct device *dev)
{
struct tpm_chip *chip = dev_get_drvdata(dev);
int ret;
if (chip->flags & TPM_CHIP_FLAG_IRQ)
tpm_tis_reenable_interrupts(chip);
ret = tpm_pm_resume(dev);
if (ret)
return ret;
/* TPM 1.2 requires self-test on resume. This function actually returns
* an error code but for unknown reason it isn't handled.
*/
if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
tpm_do_selftest(chip);
return 0;
}
EXPORT_SYMBOL_GPL(tpm_tis_resume);
#endif
MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
MODULE_DESCRIPTION("TPM Driver");
MODULE_VERSION("2.0");
MODULE_LICENSE("GPL");

View File

@ -1,156 +0,0 @@
/*
* Copyright (C) 2005, 2006 IBM Corporation
* Copyright (C) 2014, 2015 Intel Corporation
*
* Authors:
* Leendert van Doorn <leendert@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
* Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org
*
* This device driver implements the TPM interface as defined in
* the TCG TPM Interface Spec version 1.2, revision 1.0.
*
* 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, version 2 of the
* License.
*/
#ifndef __TPM_TIS_CORE_H__
#define __TPM_TIS_CORE_H__
#include "tpm.h"
enum tis_access {
TPM_ACCESS_VALID = 0x80,
TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
TPM_ACCESS_REQUEST_PENDING = 0x04,
TPM_ACCESS_REQUEST_USE = 0x02,
};
enum tis_status {
TPM_STS_VALID = 0x80,
TPM_STS_COMMAND_READY = 0x40,
TPM_STS_GO = 0x20,
TPM_STS_DATA_AVAIL = 0x10,
TPM_STS_DATA_EXPECT = 0x08,
};
enum tis_int_flags {
TPM_GLOBAL_INT_ENABLE = 0x80000000,
TPM_INTF_BURST_COUNT_STATIC = 0x100,
TPM_INTF_CMD_READY_INT = 0x080,
TPM_INTF_INT_EDGE_FALLING = 0x040,
TPM_INTF_INT_EDGE_RISING = 0x020,
TPM_INTF_INT_LEVEL_LOW = 0x010,
TPM_INTF_INT_LEVEL_HIGH = 0x008,
TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
TPM_INTF_STS_VALID_INT = 0x002,
TPM_INTF_DATA_AVAIL_INT = 0x001,
};
enum tis_defaults {
TIS_MEM_LEN = 0x5000,
TIS_SHORT_TIMEOUT = 750, /* ms */
TIS_LONG_TIMEOUT = 2000, /* 2 sec */
};
/* Some timeout values are needed before it is known whether the chip is
* TPM 1.0 or TPM 2.0.
*/
#define TIS_TIMEOUT_A_MAX max(TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_A)
#define TIS_TIMEOUT_B_MAX max(TIS_LONG_TIMEOUT, TPM2_TIMEOUT_B)
#define TIS_TIMEOUT_C_MAX max(TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_C)
#define TIS_TIMEOUT_D_MAX max(TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_D)
#define TPM_ACCESS(l) (0x0000 | ((l) << 12))
#define TPM_INT_ENABLE(l) (0x0008 | ((l) << 12))
#define TPM_INT_VECTOR(l) (0x000C | ((l) << 12))
#define TPM_INT_STATUS(l) (0x0010 | ((l) << 12))
#define TPM_INTF_CAPS(l) (0x0014 | ((l) << 12))
#define TPM_STS(l) (0x0018 | ((l) << 12))
#define TPM_STS3(l) (0x001b | ((l) << 12))
#define TPM_DATA_FIFO(l) (0x0024 | ((l) << 12))
#define TPM_DID_VID(l) (0x0F00 | ((l) << 12))
#define TPM_RID(l) (0x0F04 | ((l) << 12))
enum tpm_tis_flags {
TPM_TIS_ITPM_POSSIBLE = BIT(0),
};
struct tpm_tis_data {
u16 manufacturer_id;
int locality;
int irq;
bool irq_tested;
unsigned int flags;
wait_queue_head_t int_queue;
wait_queue_head_t read_queue;
const struct tpm_tis_phy_ops *phy_ops;
};
struct tpm_tis_phy_ops {
int (*read_bytes)(struct tpm_tis_data *data, u32 addr, u16 len,
u8 *result);
int (*write_bytes)(struct tpm_tis_data *data, u32 addr, u16 len,
const u8 *value);
int (*read16)(struct tpm_tis_data *data, u32 addr, u16 *result);
int (*read32)(struct tpm_tis_data *data, u32 addr, u32 *result);
int (*write32)(struct tpm_tis_data *data, u32 addr, u32 src);
};
static inline int tpm_tis_read_bytes(struct tpm_tis_data *data, u32 addr,
u16 len, u8 *result)
{
return data->phy_ops->read_bytes(data, addr, len, result);
}
static inline int tpm_tis_read8(struct tpm_tis_data *data, u32 addr, u8 *result)
{
return data->phy_ops->read_bytes(data, addr, 1, result);
}
static inline int tpm_tis_read16(struct tpm_tis_data *data, u32 addr,
u16 *result)
{
return data->phy_ops->read16(data, addr, result);
}
static inline int tpm_tis_read32(struct tpm_tis_data *data, u32 addr,
u32 *result)
{
return data->phy_ops->read32(data, addr, result);
}
static inline int tpm_tis_write_bytes(struct tpm_tis_data *data, u32 addr,
u16 len, const u8 *value)
{
return data->phy_ops->write_bytes(data, addr, len, value);
}
static inline int tpm_tis_write8(struct tpm_tis_data *data, u32 addr, u8 value)
{
return data->phy_ops->write_bytes(data, addr, 1, &value);
}
static inline int tpm_tis_write32(struct tpm_tis_data *data, u32 addr,
u32 value)
{
return data->phy_ops->write32(data, addr, value);
}
void tpm_tis_remove(struct tpm_chip *chip);
int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
const struct tpm_tis_phy_ops *phy_ops,
acpi_handle acpi_dev_handle);
#ifdef CONFIG_PM_SLEEP
int tpm_tis_resume(struct device *dev);
#endif
#endif

View File

@ -1,262 +0,0 @@
/*
* Copyright (C) 2015 Infineon Technologies AG
* Copyright (C) 2016 STMicroelectronics SAS
*
* Authors:
* Peter Huewe <peter.huewe@infineon.com>
* Christophe Ricard <christophe-h.ricard@st.com>
*
* Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org
*
* This device driver implements the TPM interface as defined in
* the TCG TPM Interface Spec version 1.3, revision 27 via _raw/native
* SPI access_.
*
* It is based on the original tpm_tis device driver from Leendert van
* Dorn and Kyleen Hall and Jarko Sakkinnen.
*
* 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, version 2 of the
* License.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/acpi.h>
#include <linux/freezer.h>
#include <linux/module.h>
#include <linux/spi/spi.h>
#include <linux/gpio.h>
#include <linux/of_irq.h>
#include <linux/of_gpio.h>
#include <linux/tpm.h>
#include "tpm.h"
#include "tpm_tis_core.h"
#define MAX_SPI_FRAMESIZE 64
#define mem_clear(data, size) memset((data), 0, (size))
struct tpm_tis_spi_phy {
struct tpm_tis_data priv;
struct spi_device *spi_device;
u8 *iobuf;
};
static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *data)
{
return container_of(data, struct tpm_tis_spi_phy, priv);
}
static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
u8 *in, const u8 *out)
{
struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data);
int ret = 0;
int i;
struct spi_message m;
struct spi_transfer spi_xfer;
u8 transfer_len;
spi_bus_lock(phy->spi_device->master);
while (len) {
transfer_len = min_t(u16, len, MAX_SPI_FRAMESIZE);
phy->iobuf[0] = (in ? 0x80 : 0) | (transfer_len - 1);
phy->iobuf[1] = 0xd4;
phy->iobuf[2] = addr >> 8;
phy->iobuf[3] = addr;
mem_clear(&spi_xfer, sizeof(spi_xfer));
spi_xfer.tx_buf = phy->iobuf;
spi_xfer.rx_buf = phy->iobuf;
spi_xfer.len = 4;
spi_xfer.cs_change = 1;
spi_message_init(&m);
spi_message_add_tail(&spi_xfer, &m);
ret = spi_sync_locked(phy->spi_device, &m);
if (ret < 0)
goto exit;
if ((phy->iobuf[3] & 0x01) == 0) {
// handle SPI wait states
phy->iobuf[0] = 0;
for (i = 0; i < TPM_RETRY; i++) {
spi_xfer.len = 1;
spi_message_init(&m);
spi_message_add_tail(&spi_xfer, &m);
ret = spi_sync_locked(phy->spi_device, &m);
if (ret < 0)
goto exit;
if (phy->iobuf[0] & 0x01)
break;
}
if (i == TPM_RETRY) {
ret = -ETIMEDOUT;
goto exit;
}
}
spi_xfer.cs_change = 0;
spi_xfer.len = transfer_len;
spi_xfer.delay_usecs = 5;
if (in) {
spi_xfer.tx_buf = NULL;
} else if (out) {
spi_xfer.rx_buf = NULL;
memcpy(phy->iobuf, out, transfer_len);
out += transfer_len;
}
spi_message_init(&m);
spi_message_add_tail(&spi_xfer, &m);
ret = spi_sync_locked(phy->spi_device, &m);
if (ret < 0)
goto exit;
if (in) {
memcpy(in, phy->iobuf, transfer_len);
in += transfer_len;
}
len -= transfer_len;
}
exit:
spi_bus_unlock(phy->spi_device->master);
return ret;
}
static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
u16 len, u8 *result)
{
return tpm_tis_spi_transfer(data, addr, len, result, NULL);
}
static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr,
u16 len, const u8 *value)
{
return tpm_tis_spi_transfer(data, addr, len, NULL, value);
}
static int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result)
{
int rc;
rc = data->phy_ops->read_bytes(data, addr, sizeof(u16), (u8 *)result);
if (!rc)
*result = le16_to_cpu(*result);
return rc;
}
static int tpm_tis_spi_read32(struct tpm_tis_data *data, u32 addr, u32 *result)
{
int rc;
rc = data->phy_ops->read_bytes(data, addr, sizeof(u32), (u8 *)result);
if (!rc)
*result = le32_to_cpu(*result);
return rc;
}
static int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value)
{
value = cpu_to_le32(value);
return data->phy_ops->write_bytes(data, addr, sizeof(u32),
(u8 *)&value);
}
static const struct tpm_tis_phy_ops tpm_spi_phy_ops = {
.read_bytes = tpm_tis_spi_read_bytes,
.write_bytes = tpm_tis_spi_write_bytes,
.read16 = tpm_tis_spi_read16,
.read32 = tpm_tis_spi_read32,
.write32 = tpm_tis_spi_write32,
};
static int tpm_tis_spi_probe(struct spi_device *dev)
{
struct tpm_tis_spi_phy *phy;
int irq;
phy = devm_kzalloc(&dev->dev, sizeof(struct tpm_tis_spi_phy),
GFP_KERNEL);
if (!phy)
return -ENOMEM;
phy->spi_device = dev;
phy->iobuf = devm_kmalloc(&dev->dev, MAX_SPI_FRAMESIZE, GFP_KERNEL);
if (!phy->iobuf)
return -ENOMEM;
/* If the SPI device has an IRQ then use that */
if (dev->irq > 0)
irq = dev->irq;
else
irq = -1;
return tpm_tis_core_init(&dev->dev, &phy->priv, irq, &tpm_spi_phy_ops,
NULL);
}
static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume);
static int tpm_tis_spi_remove(struct spi_device *dev)
{
struct tpm_chip *chip = spi_get_drvdata(dev);
tpm_chip_unregister(chip);
tpm_tis_remove(chip);
return 0;
}
static const struct spi_device_id tpm_tis_spi_id[] = {
{"tpm_tis_spi", 0},
{}
};
MODULE_DEVICE_TABLE(spi, tpm_tis_spi_id);
static const struct of_device_id of_tis_spi_match[] = {
{ .compatible = "st,st33htpm-spi", },
{ .compatible = "infineon,slb9670", },
{ .compatible = "tcg,tpm_tis-spi", },
{}
};
MODULE_DEVICE_TABLE(of, of_tis_spi_match);
static const struct acpi_device_id acpi_tis_spi_match[] = {
{"SMO0768", 0},
{}
};
MODULE_DEVICE_TABLE(acpi, acpi_tis_spi_match);
static struct spi_driver tpm_tis_spi_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tpm_tis_spi",
.pm = &tpm_tis_pm,
.of_match_table = of_match_ptr(of_tis_spi_match),
.acpi_match_table = ACPI_PTR(acpi_tis_spi_match),
},
.probe = tpm_tis_spi_probe,
.remove = tpm_tis_spi_remove,
.id_table = tpm_tis_spi_id,
};
module_spi_driver(tpm_tis_spi_driver);
MODULE_DESCRIPTION("TPM Driver for native SPI access");
MODULE_LICENSE("GPL");

View File

@ -1,285 +0,0 @@
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import click
import os
import time
from ragileconfig import GLOBALCONFIG, GLOBALINITPARAM, GLOBALINITCOMMAND, MAC_LED_RESET, STARTMODULE, i2ccheck_params
from ragileutil import rgpciwr, os_system
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
class AliasedGroup(click.Group):
def get_command(self, ctx, cmd_name):
rv = click.Group.get_command(self, ctx, cmd_name)
if rv is not None:
return rv
else:
return None
matches = [x for x in self.list_commands(ctx)
if x.startswith(cmd_name)]
if not matches:
return None
elif len(matches) == 1:
return click.Group.get_command(self, ctx, matches[0])
ctx.fail('Too many matches: %s' % ', '.join(sorted(matches)))
def log_os_system(cmd):
u'''execute shell command'''
status, output = os_system(cmd)
if status:
print(output)
return status, output
def write_sysfs_value(reg_name, value):
u'''write sysfs file'''
mb_reg_file = "/sys/bus/i2c/devices/" + reg_name
if (not os.path.isfile(mb_reg_file)):
print(mb_reg_file, 'not found !')
return False
try:
with open(mb_reg_file, 'w') as fd:
fd.write(value)
except Exception as error:
return False
return True
def check_driver():
u'''whether there is driver start with rg'''
status, output = log_os_system("lsmod | grep rg | wc -l")
#System execution error
if status:
return False
if output.isdigit() and int(output) > 0:
return True
else:
return False
def get_pid(name):
ret = []
for dirname in os.listdir('/proc'):
if dirname == 'curproc':
continue
try:
with open('/proc/{}/cmdline'.format(dirname), mode='r') as fd:
content = fd.read()
except Exception:
continue
if name in content:
ret.append(dirname)
return ret
def start_avs_ctrl():
if STARTMODULE.get("avscontrol", 0) == 1:
cmd = "nohup avscontrol.py start >/dev/null 2>&1 &"
rets = get_pid("avscontrol.py")
if len(rets) == 0:
os.system(cmd)
def stop_avs_ctrl():
if STARTMODULE.get('avscontrol', 0) == 1:
rets = get_pid("avscontrol.py") #
for ret in rets:
cmd = "kill "+ ret
os.system(cmd)
def start_fan_ctrl():
if STARTMODULE.get('fancontrol', 0) == 1:
cmd = "nohup fancontrol.py start >/dev/null 2>&1 &"
rets = get_pid("fancontrol.py")
if len(rets) == 0:
os.system(cmd)
def stop_fan_ctrl():
u'''disable fan timer service'''
if STARTMODULE.get('fancontrol', 0) == 1:
rets = get_pid("fancontrol.py") #
for ret in rets:
cmd = "kill "+ ret
os.system(cmd)
def rm_dev(bus, loc):
cmd = "echo 0x%02x > /sys/bus/i2c/devices/i2c-%d/delete_device" % (loc, bus)
devpath = "/sys/bus/i2c/devices/%d-%04x"%(bus, loc)
if os.path.exists(devpath):
log_os_system(cmd)
def add_dev(name, bus, loc):
if name == "lm75":
time.sleep(0.1)
pdevpath = "/sys/bus/i2c/devices/i2c-%d/" % (bus)
for i in range(1, 100):#wait for mother-bus generation, maximum wait time is 10s
if os.path.exists(pdevpath) == True:
break
time.sleep(0.1)
if i % 10 == 0:
click.echo("%%DEVICE_I2C-INIT: %s not found, wait 0.1 second ! i %d " % (pdevpath,i))
cmd = "echo %s 0x%02x > /sys/bus/i2c/devices/i2c-%d/new_device" % (name, loc, bus)
devpath = "/sys/bus/i2c/devices/%d-%04x"%(bus, loc)
if os.path.exists(devpath) == False:
os.system(cmd)
def removedevs():
devs = GLOBALCONFIG["DEVS"]
for index in range(len(devs)-1, -1, -1 ):
rm_dev(devs[index]["bus"] , devs[index]["loc"])
def adddevs():
devs = GLOBALCONFIG["DEVS"]
for dev in range(0, devs.__len__()):
add_dev(devs[dev]["name"], devs[dev]["bus"] , devs[dev]["loc"])
def checksignaldriver(name):
modisexistcmd = "lsmod | grep %s | wc -l" % name
status, output = log_os_system(modisexistcmd)
#System execution error
if status:
return False
if output.isdigit() and int(output) > 0:
return True
else:
return False
def adddriver(name, delay):
cmd = "modprobe %s" % name
if delay != 0:
time.sleep(delay)
if checksignaldriver(name) != True:
log_os_system(cmd)
def removedriver(name, delay):
realname = name.lstrip().split(" ")[0];
cmd = "rmmod -f %s" % realname
if checksignaldriver(realname):
log_os_system(cmd)
def removedrivers():
u'''remove all drivers'''
if GLOBALCONFIG is None:
click.echo("%%DEVICE_I2C-INIT: load global config failed.")
return
drivers = GLOBALCONFIG.get("DRIVERLISTS", None)
if drivers is None:
click.echo("%%DEVICE_I2C-INIT: load driver list failed.")
return
for index in range(len(drivers)-1, -1, -1 ):
delay = 0
name = ""
if type(drivers[index]) == dict and "delay" in drivers[index]:
name = drivers[index].get("name")
delay = drivers[index]["delay"]
else:
name = drivers[index]
removedriver(name, delay)
def adddrivers():
u'''add drivers'''
if GLOBALCONFIG is None:
click.echo("%%DEVICE_I2C-INIT: load global config failed.")
return
drivers = GLOBALCONFIG.get("DRIVERLISTS", None)
if drivers is None:
click.echo("%%DEVICE_I2C-INIT: load driver list failed.")
return
for index in range(0 ,len(drivers)):
delay = 0
name = ""
if type(drivers[index]) == dict and "delay" in drivers[index]:
name = drivers[index].get("name")
delay = drivers[index]["delay"]
else:
name = drivers[index]
adddriver(name, delay)
def otherinit():
for index in GLOBALINITPARAM:
delay = index.get('delay',0)
if delay !=0 :
time.sleep(1)
write_sysfs_value(index["loc"], index["value"])
for index in GLOBALINITCOMMAND:
log_os_system(index)
def unload_driver():
u'''remove devices and drivers'''
stop_avs_ctrl() # disable avs-control
stop_fan_ctrl() # disable fan-control service
removedevs() # remove other devices
removedrivers() # remove drivers
def reload_driver():
u'''reload devices and drivers'''
removedevs() # remove other devices
removedrivers() # remove drivers
time.sleep(1)
adddrivers()
adddevs()
def i2c_check(bus,retrytime = 6):
try:
i2cpath = "/sys/bus/i2c/devices/" + bus
while retrytime and not os.path.exists(i2cpath):
click.echo("%%DEVICE_I2C-HA: i2c bus abnormal, last bus %s is not exist." % i2cpath)
reload_driver()
retrytime -= 1
time.sleep(1)
except Exception as e:
click.echo("%%DEVICE_I2C-HA: %s" % str(e))
return
def set_mac_leds(data):
'''write pci register'''
pcibus = MAC_LED_RESET.get("pcibus")
slot = MAC_LED_RESET.get("slot")
fn = MAC_LED_RESET.get("fn")
bar = MAC_LED_RESET.get("bar")
offset = MAC_LED_RESET.get("offset")
val = MAC_LED_RESET.get(data, None)
if val is None:
click.echo("%%DEVICE_I2C-INIT: set_mac_leds wrong input")
return
rgpciwr(pcibus, slot, fn, bar, offset, val)
def load_driver():
u'''load devices and drivers'''
adddrivers()
adddevs()
if STARTMODULE.get("i2ccheck",0) == 1: #i2c HA
busend = i2ccheck_params.get("busend")
retrytime = i2ccheck_params.get("retrytime")
i2c_check(busend,retrytime)
start_fan_ctrl() # enable fan
start_avs_ctrl() # avs voltage-adjustment
otherinit(); # other initialization, QSFP initialization
if STARTMODULE.get("macledreset", 0) == 1:
set_mac_leds("reset")
@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS)
def main():
'''device operator'''
pass
@main.command()
def start():
'''load device '''
if check_driver():
unload_driver()
load_driver()
@main.command()
def stop():
'''stop device '''
unload_driver()
@main.command()
def restart():
'''restart device'''
unload_driver()
load_driver()
if __name__ == '__main__':
u'''device_i2c operation'''
main()

View File

@ -1,497 +0,0 @@
#!/usr/bin/env python3.9
# -*- coding: UTF-8 -*-
import click
import os
import time
import json
import traceback
from interface import Interface
import logging.handlers
from ragileutil import CompressedRotatingFileHandler
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
FILE_NAME = "/var/log/fancontrol.log"
MAX_LOG_BYTES = 20*1024*1024
BACKUP_COUNT = 9
logger = logging.getLogger("fancontrol")
logger.setLevel(logging.DEBUG)
fanctrl_log = CompressedRotatingFileHandler(FILE_NAME, mode='a', maxBytes=MAX_LOG_BYTES, backupCount=BACKUP_COUNT, encoding=None, delay=0)
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
fanctrl_log.setFormatter(formatter)
logger.addHandler(fanctrl_log)
DEBUG_FILE = "/etc/fancontrol_debug"
FAN_CTRL_CFG_FILE = "/usr/local/bin/fan_ctrl_cfg.json"
KEY_THERMAL = "Thermal"
KEY_FAN = "Fans"
KEY_PID = "PID"
KEY_OPEN_LOOP = "OpenLoop"
KEY_DEVICE = "Device"
KEY_FAN_ERROR = "FanError"
KEY_FANERROR_PWM_MAX = "Fan_Pwmmax"
KEY_INLET_TEMP = "INLET_TEMP"
KEY_OUTLET_TEMP = "OUTLET_TEMP"
KEY_SWITCH_TEMP = "SWITCH_TEMP"
KEY_TEMP = [KEY_INLET_TEMP, KEY_OUTLET_TEMP, KEY_SWITCH_TEMP]
KEY_PID_PWM_MAX = "Pwm_Max"
KEY_PID_PWM_MIN = "Pwm_Min"
KEY_PID_SETPOINT = "SetPoint"
KEY_PID_P = "P"
KEY_PID_I = "I"
KEY_PID_D = "D"
KEY_PID_TEMP_MIN = "Temp_Min"
KEY_PID_TEMP_MAX = "Temp_Max"
KEY_OPENLOOP_A = "a"
KEY_OPENLOOP_B = "b"
KEY_OPENLOOP_C = "c"
KEY_OPENLOOP_FIXUP = "fix_up"
KEY_OPENLOOP_PWM_MAX = "pwmMax"
KEY_OPENLOOP_PWM_MIN = "pwmMin"
KEY_OPENLOOP_TEMP_MIN = "tempMin"
STATUS_HIGH_CRIT = 1
STATUS_MISS_CRIT = 2
STATUS_BAD_FAN = 4
STATUS_LOW_FAN = 8
STATUS_MISS_ERR = 16
class AliasedGroup(click.Group):
def get_command(self, ctx, cmd_name):
rv = click.Group.get_command(self, ctx, cmd_name)
if rv is not None:
return rv
else:
return None
matches = [x for x in self.list_commands(ctx)
if x.startswith(cmd_name)]
if not matches:
return None
elif len(matches) == 1:
return click.Group.get_command(self, ctx, matches[0])
ctx.fail('Too many matches: %s' % ', '.join(sorted(matches)))
def fanctrl_debug_log(s):
# s = s.decode('utf-8').encode('gb2312')
if os.path.isfile(DEBUG_FILE):
logger.debug(s)
class OpenLoop():
def __init__(self):
self.a = 0
self.b = 0
self.c = 0
self.fix_up = 0
self.pwmMax = 0
self.pwmMin = 0
self.temp = 0
self.tempMin = 0
def calcPwm(self):
if self.temp < self.tempMin:
return self.pwmMin
pwm = self.a * self.temp * self.temp + self.b * self.temp + self.c
pwm = (pwm / 2.56)
pwm = min(pwm, self.pwmMax)
pwm = max(pwm, self.pwmMin)
return pwm
class FanPid():
def __init__(self):
self.pwmMin = 30
self.pwmMax = 100
self.SetPoint = 89
self.D = 0.196
self.I = 0.196
self.P = 1.176
self.tempMin = 28.0
self.tempMax = 45.0
self.pwms = [30, 30]
self.temps = [-1, -1, -1]
self.last_temp = -1
self.sensor = KEY_SWITCH_TEMP
def calcPwm(self):
temp_delta = self.temps[2] - self.last_temp
temp_sp_delta = self.temps[2] - self.SetPoint
temp_last_delta = ((self.temps[2] - self.temps[1]) - (self.temps[1] - self.temps[0]))
delta_pwm = self.P * temp_delta + self.I * temp_sp_delta + self.D * temp_last_delta
self.temps[0] = self.temps[1]
self.temps[1] = self.temps[2]
self.last_temp = self.temps[2]
self.pwms[0] = self.pwms[1]
self.pwms[1] = self.pwms[0] + delta_pwm
self.pwms[1] = max(self.pwms[1], self.pwmMin)
self.pwms[1] = min(self.pwms[1], self.pwmMax)
return self.pwms[1]
class FanControl():
def __init__(self):
self.status = 0
self.fan_status = 0
self.error_time = 0
self.low_time = 0
self.fan_pwm = 40
self.fanerr_pwmmax = 0
self.interface = Interface()
self.temps = {}
self.tempsMax = {}
self.tempsMin = {}
self.tempStatus = {}
self.tempCritTime = {}
self.tempMissTime = {}
self.fans = {}
self.fanStatus = {}
self.fanErrTime = {}
self.fanLowTime = {}
self.fanPid = None
self.openloop = None
self.isBuildin = 0
self.isLiquid = 0
self.eeproms = {}
self.airflow = ""
self.pid_switch = 1
self.openloop_switch = 1
def doGetAirFlow(self):
if self.isLiquid == 1:
return "Liquid"
# PSU and Fan is buildin using Tlve2
if self.isBuildin == 1:
productName = self.interface.get_productname()
if productName != "":
tmp = productName.split("-")
fanairflow = tmp[-1]
if fanairflow == "R":
return "exhaust"
else:
return "intake"
elif self.isBuildin == 0:
return self.interface.get_airflow()
return ""
def doFanCtrlInit(self):
if os.path.isfile(FAN_CTRL_CFG_FILE):
fh = open(FAN_CTRL_CFG_FILE)
if not fh:
logger.error("Config file %s doesn't exist" % FAN_CTRL_CFG_FILE)
return False
cfg_json = json.load(fh)
if not cfg_json:
logger.error('Load config file %s failed' % FAN_CTRL_CFG_FILE)
fh.close()
return False
cfg_keys = [KEY_THERMAL, KEY_FAN, KEY_PID, KEY_OPEN_LOOP, KEY_DEVICE, KEY_FAN_ERROR]
for key in cfg_keys:
if key not in cfg_json:
logger.error('Key %s not present in cfg file' % key)
return False
thermal_json = cfg_json[KEY_THERMAL]
fan_json = cfg_json[KEY_FAN]
pid_json = cfg_json[KEY_PID]
openloop_json = cfg_json[KEY_OPEN_LOOP]
device_json = cfg_json[KEY_DEVICE]
fan_error_json = cfg_json[KEY_FAN_ERROR]
#init fanerror
self.fanerr_pwmmax = fan_error_json["Fan_Pwmmax"]
# Get Airflow
self.isBuildin = device_json["Buildin"]
self.isLiquid = device_json["Liquid"]
self.airflow = self.doGetAirFlow()
if self.airflow == "":
logger.warning("Cannot get airflow from device!")
self.pid_switch = device_json["PID"]
self.openloop_switch = device_json["OpenLoop"]
if self.pid_switch == 0 and self.openloop_switch == 0:
logger.warning("No PID and OpenLoop found!")
# Init openloop
self.openloop = OpenLoop()
self.openloop.a = openloop_json[KEY_OPENLOOP_A]
self.openloop.b = openloop_json[KEY_OPENLOOP_B]
self.openloop.c = openloop_json[KEY_OPENLOOP_C]
self.openloop.fix_up = openloop_json[KEY_OPENLOOP_FIXUP]
self.openloop.pwmMax = openloop_json[KEY_OPENLOOP_PWM_MAX]
self.openloop.pwmMin = openloop_json[KEY_OPENLOOP_PWM_MIN]
self.openloop.tempMin = openloop_json[KEY_OPENLOOP_TEMP_MIN]
# Init PID
self.fanPid = FanPid()
self.fanPid.pwmMax = pid_json[KEY_PID_PWM_MAX]
self.fanPid.pwmMin = pid_json[KEY_PID_PWM_MIN]
self.fanPid.SetPoint = pid_json[KEY_PID_SETPOINT]
self.fanPid.P = pid_json[KEY_PID_P]
self.fanPid.I = pid_json[KEY_PID_I]
self.fanPid.D = pid_json[KEY_PID_D]
self.fanPid.tempMin = pid_json[KEY_PID_TEMP_MIN]
self.fanPid.tempMax = pid_json[KEY_PID_TEMP_MAX]
# Init thermal setting
for key, item in list(thermal_json.items()):
fanctrl_debug_log("%s %s " % (key,item))
if key not in KEY_TEMP:
logger.error('Key %s not present in cfg file' % key)
return False
self.temps[item] = -1.0
self.tempsMax[item] = self.interface.get_thermal_temp_max(item)
self.tempsMin[item] = self.interface.get_thermal_temp_min(item)
self.tempStatus[item] = 0
self.tempMissTime[item] = [0, 0]
self.tempCritTime[item] = [0, 0]
if key == self.fanPid.sensor:
self.fanPid.sensor = item
# Init fans setting
for key, item in list(fan_json.items()):
self.fans[key] = item
self.fanStatus[key] = 0
self.fanErrTime[key] = [0, 0]
self.fanLowTime[key] = [0, 0]
fh.close()
else:
logger.error('%s is not a file' % FAN_CTRL_CFG_FILE)
return False
fanctrl_debug_log("Device AirFlow: %s" % (self.airflow))
self.updateThermal()
self.fanPid.last_temp = self.temps[self.fanPid.sensor]
for i in range(3):
self.fanPid.temps[i] = self.temps[self.fanPid.sensor]
return True
def setFanSpeed(self, speed):
return self.interface.set_fan_speed_pwm(speed)
def updateThermal(self):
for key in self.temps:
self.temps[key] = self.interface.get_thermal_temp(key)
fanctrl_debug_log("%s temps %d C" % (key, self.temps[key]))
if self.temps[KEY_INLET_TEMP] >= self.tempsMax[KEY_INLET_TEMP] or self.temps[KEY_INLET_TEMP] <= -99999:
self.temps[KEY_INLET_TEMP] = self.tempsMax[KEY_INLET_TEMP]
self.openloop.temp = self.temps[KEY_INLET_TEMP]
self.fanPid.temps[2] = self.temps[KEY_INLET_TEMP]
def checkThermal(self):
thermal_cnt = 0
for key in self.temps:
if self.temps[key] <= -9999:
if self.tempStatus[key] & STATUS_MISS_CRIT != 0:
self.tempMissTime[key][0] = time.time()
else:
self.tempMissTime[key][1] = time.time()
self.tempStatus[key] = self.tempStatus[key] | STATUS_MISS_CRIT
if self.tempMissTime[key][1] - self.tempMissTime[key][0] > 15:
logger.warning("%s Read Invaild Temperautre %d " % (key, self.temps[key]))
self.tempStatus[key] = self.tempStatus[key] | STATUS_MISS_ERR
else:
self.tempStatus[key] = self.tempStatus[key] & ~(STATUS_MISS_CRIT | STATUS_MISS_ERR)
if self.temps[key] >= self.tempsMax[key]:
self.tempCritTime[key][0] = time.time()
self.tempStatus[key] = self.tempStatus[key] | STATUS_HIGH_CRIT
logger.warning("%s Temperautre %d >= High Threshold %d" % (key, self.temps[key], self.tempsMax[key]))
elif self.tempStatus[key] & (STATUS_HIGH_CRIT) != 0:
self.tempCritTime[key][1] = time.time()
logger.warning("%s Temperautre %d Recovery" % (key, self.temps[key]))
if self.tempCritTime[key][1] - self.tempCritTime[key][0] > 300:
self.tempStatus[key] = self.tempStatus[key] & ~(STATUS_HIGH_CRIT)
if self.tempStatus[key] & ~(STATUS_MISS_CRIT) != 0:
thermal_cnt = thermal_cnt + 1
self.status = thermal_cnt
fanctrl_debug_log("Thermal error num %d" % self.status)
def checkFanSpeed(self):
fan_error_cnt = 0
for key, item in list(self.fans.items()):
speed = self.interface.get_fan_speed_rpm(item)
rpm_max = self.interface.get_fan_rpm_max()
if self.fan_pwm == 100 and speed < rpm_max * 0.7:
if self.fanStatus[key] & STATUS_BAD_FAN != 0:
self.fanErrTime[key][0] = time.time()
else:
self.fanErrTime[key][1] = time.time()
self.fanStatus[key] = self.fanStatus[key] | STATUS_BAD_FAN
if self.fanErrTime[key][1] - self.fanErrTime[key][0] >= 30:
logger.warning("%s PWM is %d but Speed %d <= %d RPM" % (item, self.fan_pwm, speed, rpm_max * 0.7))
else:
self.fanStatus[key] = self.fanStatus[key] & ~(STATUS_BAD_FAN)
if speed < 1000:
if self.fanStatus[key] & STATUS_LOW_FAN != 0:
self.fanLowTime[key][0] = time.time()
else:
self.fanLowTime[key][1] = time.time()
self.fanStatus[key] = self.fanStatus[key] | STATUS_LOW_FAN
if self.fanLowTime[key][1] - self.fanLowTime[key][0] > 30:
logger.warning("%s Speed %d <= %d RPM" % (item, speed, 1000))
else:
self.fanStatus[key] = self.fanStatus[key] & ~(STATUS_LOW_FAN)
fanctrl_debug_log("%s speed %d RPM" % (key, speed))
if self.fanStatus[key] != 0:
fan_error_cnt = fan_error_cnt + 1
self.fan_status = fan_error_cnt
fanctrl_debug_log("Fan error num %d" % fan_error_cnt)
def doApplyPolicy(self):
if self.isLiquid == 1:
return
self.fan_pwm = 0
if self.openloop_switch == 1:
openloop_pwm = int(self.openloop.calcPwm())
fanctrl_debug_log("OpenLoop pwm %d" % (openloop_pwm))
self.fan_pwm = max(self.fan_pwm, openloop_pwm)
if self.pid_switch == 1:
pid_pwm = int(self.fanPid.calcPwm())
fanctrl_debug_log("PID pwm %d" % (pid_pwm))
self.fan_pwm = max(self.fan_pwm, pid_pwm)
# Check fan presence
if self.interface.get_fan_presence() == False:
logger.warning("Fan presence check false, set fan pwm to 100")
self.fan_pwm = self.fanerr_pwmmax
if self.fan_status != 0 or self.status != 0:
self.fan_pwm = self.fanerr_pwmmax
fanctrl_debug_log("Fan Speed set to %d pwm" % self.fan_pwm)
for i in range(3):
ret = self.setFanSpeed(self.fan_pwm)
if ret == False:
logger.warning("Fan speed set %d pwm failed, retry %d times" % (self.fan_pwm, i + 1))
continue
break
def doBoardFanLedCtrl(self):
if self.interface.get_fan_status() != False and self.interface.get_fan_presence() != False and self.fan_status == 0:
fanctrl_debug_log("Fan status good setting LED to green")
self.interface.set_fan_board_led("green")
else:
fanctrl_debug_log("Fan status error setting LED to red")
self.interface.set_fan_board_led("red")
def doBoardPsuLedCtrl(self):
if self.interface.get_psu_status() != False:
fanctrl_debug_log("PSU status good setting LED to green")
self.interface.set_psu_board_led("green")
else:
fanctrl_debug_log("PSU status error setting LED to red")
self.interface.set_psu_board_led("red")
def doSysLedCtrl(self):
self.interface.set_sysled("green")
def run(interval, fanCtrol):
loop = 0
# waitForDocker()
fanCtrol.setFanSpeed(fanCtrol.fan_pwm) #init set fan speed to 50 pwm
fanCtrol.doFanCtrlInit()
if fanCtrol.airflow == "Liquid":
logger.warning('Liquid device stopping fancontrol')
return True
while True:
try:
if loop % 5 == 0: # Fan speed control
try:
fanCtrol.updateThermal()
except Exception as e:
logger.error('Failed: Update Thermal, %s' % str(e))
logger.error('%s' % traceback.format_exc())
time.sleep(3)
continue
try:
fanCtrol.checkThermal()
except Exception as e:
logger.error('Failed: Check Thermal, %s' % str(e))
logger.error('%s' % traceback.format_exc())
time.sleep(3)
continue
try:
fanCtrol.checkFanSpeed()
except Exception as e:
logger.error('Failed: Check Fan Speed, %s' % str(e))
logger.error('%s' % traceback.format_exc())
time.sleep(3)
continue
try:
fanCtrol.doApplyPolicy()
except Exception as e:
logger.error('Failed: Apply Policy, %s' % str(e))
logger.error('%s' % traceback.format_exc())
time.sleep(3)
continue
try:
fanCtrol.doBoardFanLedCtrl()
except Exception as e:
logger.error('Failed: Led Control, %s' % str(e))
logger.error('%s' % traceback.format_exc())
time.sleep(3)
continue
try:
fanCtrol.doBoardPsuLedCtrl()
except Exception as e:
logger.error('Failed: Led Control, %s' % str(e))
logger.error('%s' % traceback.format_exc())
time.sleep(3)
continue
try:
fanCtrol.doSysLedCtrl()
except Exception as e:
logger.error('Failed: Led Control, %s' % str(e))
logger.error('%s' % traceback.format_exc())
time.sleep(3)
continue
time.sleep(interval)
loop += interval
except Exception as e:
traceback.print_exc()
logger.error(str(e))
@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS)
def main():
'''device operator'''
pass
@main.command()
def start():
'''start fan control'''
logger.info("FANCTROL start")
fanCtrol = FanControl()
interval = 1
run(interval, fanCtrol)
@main.command()
def stop():
'''stop fan control '''
logger.info("FANCTROL stop")
# device_i2c operation
if __name__ == '__main__':
main()

View File

@ -1,77 +0,0 @@
from sonic_platform.chassis import Chassis
class Interface():
def __init__(self):
self.chassis = Chassis()
self.fan_list = self.chassis._fan_list
self.thermal_list = self.chassis._thermal_list
self.psu_list = self.chassis._psu_list
# Device
def get_productname(self):
return self.chassis.get_name()
def set_sysled(self, color):
return self.thermal_list[0].set_sys_led(color)
# Thermal
def get_thermal_temp_max(self, name):
for thermal in self.thermal_list:
if name == thermal.get_real_name():
return thermal.get_high_threshold()
def get_thermal_temp_min(self, name):
for thermal in self.thermal_list:
if name == thermal.get_real_name():
return thermal.get_low_threshold()
def get_thermal_temp(self, name):
for thermal in self.thermal_list:
if name == thermal.get_real_name():
return thermal.get_temperature()
# Fans
def set_fan_speed_pwm(self, speed):
return self.fan_list[0].set_speed_pwm(speed)
def get_fan_status(self):
for fan in self.fan_list:
if fan.get_status() == False:
return False
return True
def get_fan_presence(self):
for fan in self.fan_list:
if fan.get_presence() == False:
return False
return True
def set_fan_board_led(self, color):
return self.fan_list[0].set_status_led(color)
def get_fan_speed_rpm(self, name):
for fan in self.fan_list:
if name == fan.get_name():
return fan.get_speed_rpm()
return 0
def get_fan_rpm_max(self):
return self.fan_list[0].get_high_critical_threshold()
def get_airflow(self):
tmp1 = self.fan_list[0].get_direction()
tmp2 = self.fan_list[0].get_direction()
for fan in self.fan_list:
tmp1 = fan.get_direction()
if tmp1 != tmp2:
return "F2B"
tmp2 = tmp1
return tmp2
# Psus
def get_psu_status(self):
for psu in self.psu_list:
if psu.get_powergood_status == False:
return False
return True
def set_psu_board_led(self, color):
return self.psu_list[0].set_status_led(color)

View File

@ -1,92 +0,0 @@
#!/usr/bin/python3
# * onboard sensors
#
import os
import sys
from sonic_platform.redfish_api import Redfish_Api
def get_machine_info():
if not os.path.isfile('/host/machine.conf'):
return None
machine_vars = {}
with open('/host/machine.conf') as machine_file:
for line in machine_file:
tokens = line.split('=')
if len(tokens) < 2:
continue
machine_vars[tokens[0]] = tokens[1].strip()
return machine_vars
def get_platform_info(machine_info):
if machine_info is not None:
if 'onie_platform' in machine_info:
return machine_info['onie_platform']
elif 'aboot_platform' in machine_info:
return machine_info['aboot_platform']
return None
PLATFORM_ROOT_PATH = '/usr/share/sonic/device'
platform = None
def get_platform_name():
global platform
platform = get_platform_info(get_machine_info())
return platform
val = get_platform_name()
sys.path.append("/".join([PLATFORM_ROOT_PATH, platform]))
def print_console(str):
print(str)
def print_platform():
platform_info = get_platform_name()
print_console(platform_info)
print_console('Adapter: Ragile Platform Management Controller')
print_console("")
def get_sensor():
sensor = Redfish_Api().get_thresholdSensors()
ctrl = sensor["Sensors"]
list_sensor =[]
for item in ctrl:
name = item.get("@odata.id").split("/",9)[9]
now = item.get("Reading")
min = item.get("Thresholds").get("LowerFatal").get("Reading")
max = item.get("Thresholds").get("UpperFatal").get("Reading")
unit = item.get("ReadingUnits")
if unit == "Amps":
unit = "A"
if min == (-1000):
min = (min/1000)
elif unit == "Volts":
unit = "V"
tmp = {}
tmp["name"]= name
tmp["now"] = ("%.3f" % now)
tmp["min"] = ("%.3f" % min)
tmp["max"] = ("%.3f" % max)
tmp["unit"] = unit
list_sensor.append(tmp)
return list_sensor
def print_boarddcdc():
val_ret = get_sensor()
print_info_str = ""
toptile = "Onboard Sensors:"
errformat = " {id:<26} : {errmsg}"
formatstr = " {name:<26} : {now:<6} {unit:<1} (Min = {min:<6} {unit:<1} , Max = {max:<6} {unit:<1} )"
if len(val_ret) != 0:
print_info_str += toptile + '\n'
for item in val_ret:
realformat = formatstr if item.get('errcode', 0) == 0 else errformat
print_info_str += realformat.format(**item) + '\n'
print_console(print_info_str)
def getsensors():
print_platform()
print_boarddcdc()
if __name__ == "__main__":
getsensors()

View File

@ -1,228 +0,0 @@
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# -------------------------------------------------------------------------------
# Name: ragileconfig.py
# Purpose: block the difference between various product/onie version for other module
#
# Author: rd
#
# Created: 02/07/2018
# Copyright: (c) rd 2018
# -------------------------------------------------------------------------------
import sys
import os
import logging
from rgutil.baseutil import get_machine_info
from rgutil.baseutil import get_platform_info
__all__ = [
"getdeviceplatform",
"get_rjconfig_info",
"MONITOR_CONST",
"MAILBOX_DIR",
"DEVICE",
"GLOBALCONFIG",
"GLOBALINITPARAM",
"GLOBALINITCOMMAND",
"MAC_LED_RESET",
"STARTMODULE",
"fanloc",
"RAGILE_CARDID",
"RAGILE_PRODUCTNAME",
"RAGILE_PART_NUMBER",
"RAGILE_LABEL_REVISION",
"RAGILE_MAC_SIZE",
"RAGILE_MANUF_NAME",
"RAGILE_MANUF_COUNTRY",
"RAGILE_VENDOR_NAME",
"RAGILE_DIAG_VERSION",
"RAGILE_SERVICE_TAG",
"E2_PROTECT",
"E2_LOC",
"FAN_PROTECT",
"FANS_DEF",
"MONITOR_FANS_LED",
"MONITOR_SYS_FAN_LED",
"MONITOR_SYS_PSU_LED",
"MONITOR_FAN_STATUS",
"MONITOR_PSU_STATUS",
"MONITOR_DEV_STATUS",
"MONITOR_DEV_STATUS_DECODE",
"DEV_LEDS",
"MAC_AVS_PARAM",
"MAC_DEFAULT_PARAM",
"FRULISTS",
"rg_eeprom",
"i2ccheck_params",
"FANCTROLDEBUG",
"DEVMONITORDEBUG",
]
def getdeviceplatform():
x = get_platform_info(get_machine_info())
if x != None:
filepath = "/usr/share/sonic/device/" + x
return filepath
else:
return None
platform = get_platform_info(get_machine_info())
platformpath = getdeviceplatform()
MAILBOX_DIR = "/sys/bus/i2c/devices/"
grtd_productfile = (platform + "_config").replace("-", "_")
common_productfile = "ragilecommon"
configfile_pre = "/usr/local/bin/"
sys.path.append(platformpath)
sys.path.append(configfile_pre)
def get_rjconfig_info(attr_key):
rjconf_filename = platformpath + "/plugins" + "/rj.conf"
if not os.path.isfile(rjconf_filename):
return None
with open(rjconf_filename) as rjconf_file:
for line in rjconf_file:
tokens = line.split("=")
if len(tokens) < 2:
continue
if tokens[0] == attr_key:
return tokens[1].strip()
return None
#####BMC-Password###
OPENBMC_PASSWORD = get_rjconfig_info("OPENBMC_PASSWORD")
OPENBMC_PASSWORD = OPENBMC_PASSWORD if (OPENBMC_PASSWORD != None) else "0penBmc"
############################################################################################
## if there is no specific file, use common file
module_product = None
if os.path.exists(configfile_pre + grtd_productfile + ".py"):
module_product = __import__(grtd_productfile, globals(), locals(), [], 0)
elif os.path.exists(configfile_pre + common_productfile + ".py"):
module_product = __import__(common_productfile, globals(), locals(), [], 0)
else:
logging.info("No Configuration existed, quit")
exit(-1)
############################################################################################
DEVICE = module_product.DEVICE
##########Driver loading needs parameters
# get different product configuration
RAGILE_GLOBALCONFIG = {
"DRIVERLISTS": module_product.DRIVERLISTS,
"QSFP": {
"startbus": module_product.PCA9548START,
"endbus": module_product.PCA9548BUSEND,
},
"DEVS": DEVICE,
}
GLOBALCONFIG = RAGILE_GLOBALCONFIG
GLOBALINITPARAM = module_product.INIT_PARAM
GLOBALINITCOMMAND = module_product.INIT_COMMAND
fancontrol_loc = module_product.fancontrol_loc
fancontrol_config_loc = module_product.fancontrol_config_loc
MAC_LED_RESET = module_product.MAC_LED_RESET
###########Stat-up module parameters
STARTMODULE = module_product.STARTMODULE
FIRMWARE_TOOLS = module_product.FIRMWARE_TOOLS
##########Manufacturing-Test need parameters
FACTESTMODULE = module_product.FACTESTMODULE
TESTCASE = module_product.TESTCASE
menuList = module_product.menuList
alltest = module_product.alltest
diagtestall = module_product.diagtestall
looptest = module_product.looptest
fanloc = module_product.fanloc
fanlevel = module_product.fanlevel # fan adjustment level
TEMPIDCHANGE = module_product.TEMPIDCHANGE
CPLDVERSIONS = module_product.CPLDVERSIONS
RAGILE_CARDID = module_product.RAGILE_CARDID
RAGILE_PRODUCTNAME = module_product.RAGILE_PRODUCTNAME
RAGILE_PART_NUMBER = module_product.RAGILE_PART_NUMBER
RAGILE_LABEL_REVISION = module_product.RAGILE_LABEL_REVISION
RAGILE_ONIE_VERSION = module_product.RAGILE_ONIE_VERSION
RAGILE_MAC_SIZE = module_product.RAGILE_MAC_SIZE
RAGILE_MANUF_NAME = module_product.RAGILE_MANUF_NAME
RAGILE_MANUF_COUNTRY = module_product.RAGILE_MANUF_COUNTRY
RAGILE_VENDOR_NAME = module_product.RAGILE_VENDOR_NAME
RAGILE_DIAG_VERSION = module_product.RAGILE_DIAG_VERSION
RAGILE_SERVICE_TAG = module_product.RAGILE_SERVICE_TAG
E2_PROTECT = module_product.E2_PROTECT
E2_LOC = module_product.E2_LOC
FAN_PROTECT = module_product.FAN_PROTECT
FANS_DEF = module_product.FANS_DEF
MONITOR_SYS_LED = module_product.MONITOR_SYS_LED
MONITOR_FANS_LED = module_product.MONITOR_FANS_LED
MONITOR_SYS_FAN_LED = module_product.MONITOR_SYS_FAN_LED
MONITOR_SYS_PSU_LED = module_product.MONITOR_SYS_PSU_LED
MONITOR_FAN_STATUS = module_product.MONITOR_FAN_STATUS
MONITOR_PSU_STATUS = module_product.MONITOR_PSU_STATUS
MONITOR_DEV_STATUS = module_product.MONITOR_DEV_STATUS
MONITOR_DEV_STATUS_DECODE = module_product.MONITOR_DEV_STATUS_DECODE
DEV_MONITOR_PARAM = module_product.DEV_MONITOR_PARAM
SLOT_MONITOR_PARAM = module_product.SLOT_MONITOR_PARAM
DEV_LEDS = module_product.DEV_LEDS
MEM_SLOTS = module_product.MEM_SLOTS
MAC_AVS_PARAM = module_product.MAC_AVS_PARAM
MAC_DEFAULT_PARAM = module_product.MAC_DEFAULT_PARAM
E2TYPE = module_product.E2TYPE
FRULISTS = module_product.FRULISTS
rg_eeprom = "%d-%04x/eeprom" % (E2_LOC["bus"], E2_LOC["devno"])
factest_module = module_product.factest_module
LOCAL_LED_CONTROL = module_product.LOCAL_LED_CONTROL
PCIe_DEV_LIST = module_product.PCIe_DEV_LIST
PCIe_SPEED_ITEM = module_product.PCIe_SPEED_ITEM
i2ccheck_params = module_product.i2ccheck_params
class MONITOR_CONST:
TEMP_MIN = module_product.MONITOR_TEMP_MIN
K = module_product.MONITOR_K
MAC_IN = module_product.MONITOR_MAC_IN
DEFAULT_SPEED = module_product.MONITOR_DEFAULT_SPEED
MAX_SPEED = module_product.MONITOR_MAX_SPEED
MIN_SPEED = module_product.MONITOR_MIN_SPEED
MAC_ERROR_SPEED = module_product.MONITOR_MAC_ERROR_SPEED
FAN_TOTAL_NUM = module_product.MONITOR_FAN_TOTAL_NUM
MAC_UP_TEMP = module_product.MONITOR_MAC_UP_TEMP
MAC_LOWER_TEMP = module_product.MONITOR_MAC_LOWER_TEMP
MAC_MAX_TEMP = module_product.MONITOR_MAC_MAX_TEMP
MAC_WARNING_THRESHOLD = module_product.MONITOR_MAC_WARNING_THRESHOLD
OUTTEMP_WARNING_THRESHOLD = module_product.MONITOR_OUTTEMP_WARNING_THRESHOLD
BOARDTEMP_WARNING_THRESHOLD = module_product.MONITOR_BOARDTEMP_WARNING_THRESHOLD
CPUTEMP_WARNING_THRESHOLD = module_product.MONITOR_CPUTEMP_WARNING_THRESHOLD
INTEMP_WARNING_THRESHOLD = module_product.MONITOR_INTEMP_WARNING_THRESHOLD
MAC_CRITICAL_THRESHOLD = module_product.MONITOR_MAC_CRITICAL_THRESHOLD
OUTTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_OUTTEMP_CRITICAL_THRESHOLD
BOARDTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_BOARDTEMP_CRITICAL_THRESHOLD
CPUTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_CPUTEMP_CRITICAL_THRESHOLD
INTEMP_CRITICAL_THRESHOLD = module_product.MONITOR_INTEMP_CRITICAL_THRESHOLD
CRITICAL_NUM = module_product.MONITOR_CRITICAL_NUM
SHAKE_TIME = module_product.MONITOR_SHAKE_TIME
MONITOR_INTERVAL = module_product.MONITOR_INTERVAL
MONITOR_FALL_TEMP = module_product.MONITOR_FALL_TEMP
MONITOR_MAC_SOURCE_SYSFS = module_product.MONITOR_MAC_SOURCE_SYSFS
MONITOR_MAC_SOURCE_PATH = module_product.MONITOR_MAC_SOURCE_PATH
FANCTROLDEBUG = 0 # 1 means enable
DEVMONITORDEBUG = 0 # 1 means enable

View File

@ -1,8 +0,0 @@
#!/bin/bash
#docker exec -i pmon sensors "$@"
#To probe sensors not part of lm-sensors
if [ -r /usr/local/bin/platform_sensors.py ]; then
python /usr/local/bin/platform_sensors.py
fi

View File

@ -1,15 +0,0 @@
[Unit]
Description= Ragile Global Initialize I2c drivers.
After=local-fs.target
Before=pmon.service ntp.service
DefaultDependencies=no
[Service]
Type=oneshot
ExecStart=/usr/local/bin/device_i2c.py start
ExecStop=/usr/local/bin/device_i2c.py stop
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target

View File

@ -1,12 +0,0 @@
[Unit]
Description= Fancontrol for Device.
After=privatenetwork.service
DefaultDependencies=no
[Service]
ExecStart=/usr/local/bin/fancontrol.py start
Restart=on-failure
[Install]
WantedBy=multi-user.target

View File

@ -1,24 +0,0 @@
PWD = $(shell pwd)
EXTRA_CFLAGS:= -I$(M)/include
EXTRA_CFLAGS+= -Wall
SUB_BUILD_DIR = $(PWD)/build
SERVICE_DIR = $(PWD)/service
INSTALL_DIR = $(SUB_BUILD_DIR)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR)
INSTALL_SCRIPT_DIR = $(SUB_BUILD_DIR)/usr/local/bin
INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python3.9/dist-packages
INSTALL_SERVICE_DIR = $(SUB_BUILD_DIR)/lib/systemd/system
INSTALL_ETC_DIR = $(SUB_BUILD_DIR)/etc
UNSUPPORT_KERVER = 4.9.189
all:
@if [ ! -d ${INSTALL_LIB_DIR} ]; then mkdir -p ${INSTALL_LIB_DIR} ;fi
@if [ -d $(PWD)/lib/ ]; then cp -r $(PWD)/lib/* ${INSTALL_LIB_DIR} ;fi
@if [ ! -d ${INSTALL_SCRIPT_DIR} ]; then mkdir -p ${INSTALL_SCRIPT_DIR} ;fi
@if [ -d $(PWD)/script/ ]; then cp -r $(PWD)/script/* ${INSTALL_SCRIPT_DIR} ;fi
@if [ ! -d ${INSTALL_ETC_DIR} ]; then mkdir -p ${INSTALL_ETC_DIR} ;fi
@if [ -d $(INSTALL_SCRIPT_DIR) ]; then chmod +x $(INSTALL_SCRIPT_DIR)/* ;fi
@if [ ! -d ${INSTALL_SERVICE_DIR} ]; then mkdir -p ${INSTALL_SERVICE_DIR} ;fi
if [ -d $(SERVICE_DIR) ]; then cp -r $(SERVICE_DIR)/* $(INSTALL_SERVICE_DIR) ;fi
clean:
rm -rf $(SUB_BUILD_DIR)

View File

@ -1,67 +0,0 @@
[products]
6 = BMCEEPROM
17 = CPUM-C7EDN6-U2
26 = EMMC-CARD
33 = RA-B6010-48GT4X
# 1 TLV EEPROM 0x56
# 2 X86 CPU EEPROM
# 3 BMC EEPROM
# 4 CPU BASE_BOARD EEPROM 0x57
# 5 MAC BOARD EEPROM
# 6.Line card EEPROM (128)
# 7.Fan adapter EEPROM
# 8.Fan the small plate EEPROM
# 9.PSU FRU EEPROM
[typename]
1= tlveeprom
2= x86cpueeprom
3= bmceeprom
4= cpueeprom
5= maceeprom
6= sloteeprom
7= fanconnecteeprom
8= M1HFANI-F
9= M1HFANI-R
A= M2HFANI-F
B= M2HFANI-R
C= psu
M = RA-EMMC-CARD
Q = ibvbeeprom
[BMCEEPROM-3]
boardinfoarea.ispresent = 1
boardinfoarea.boardManufacturer = Ragile
boardinfoarea.boradProductName = BMC
boardinfoarea.boardSerialNumber = 0000000000000
boardinfoarea.boardPartNumber = BMC
boardinfoarea.FRUFileID = 6-3
boardinfoarea.boardextra1 = AA
[RA-B6010-48GT4X-4]
productInfoArea.ispresent = 1
productInfoArea.productManufacturer = Ragile
productInfoArea.productName = RA-B6010-48GT4X
productInfoArea.productPartModelName = RA-B6010-48GT4X
productInfoArea.productVersion = 00
productInfoArea.productSerialNumber = 0000000000000
productInfoArea.FRUFileID = 33-4
productInfoArea.productExtra1 = 2020-12-20
productInfoArea.productExtra2 = 1a2b3c4d5e6f
productInfoArea.productExtra3 = 2
boardinfoarea.ispresent = 1
boardinfoarea.boardManufacturer = Ragile
boardinfoarea.boradProductName = RA-B6010-48GT4X
boardinfoarea.boardSerialNumber = 0000000000000
boardinfoarea.boardPartNumber = RA-B6010-48GT4X
boardinfoarea.FRUFileID = 33-4
boardinfoarea.boardextra1 = AA
[EMMC-CARD-M]
boardinfoarea.ispresent = 1
boardinfoarea.boardManufacturer = Ragile
boardinfoarea.boradProductName = EMMC-CARD
boardinfoarea.boardSerialNumber = 0000000000000
boardinfoarea.boardPartNumber = RA-EMMC-CARD
boardinfoarea.FRUFileID = 26-M
boardinfoarea.boardextra1 = AA

View File

@ -1,64 +0,0 @@
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import os
import syslog
import logging
import subprocess
import shlex
SYSLOG_IDENTIFIER = "LOGUTIL"
# ========================== Syslog wrappers ==========================
def log_info(msg,log_type=SYSLOG_IDENTIFIER, also_print_to_console=False):
syslog.openlog(log_type)
syslog.syslog(syslog.LOG_INFO, msg)
syslog.closelog()
if also_print_to_console:
click.echo(msg)
def log_debug(msg, log_type=SYSLOG_IDENTIFIER, also_print_to_console=False):
try:
syslog.openlog(log_type)
syslog.syslog(syslog.LOG_DEBUG, msg)
syslog.closelog()
if also_print_to_console:
click.echo(msg)
except Exception as e:
print(str(e))
def log_warning(msg, log_type=SYSLOG_IDENTIFIER, also_print_to_console=False):
syslog.openlog(log_type)
syslog.syslog(syslog.LOG_WARNING, msg)
syslog.closelog()
if also_print_to_console:
click.echo(msg)
def log_error(msg, log_type=SYSLOG_IDENTIFIER, also_print_to_console=False):
syslog.openlog(log_type)
syslog.syslog(syslog.LOG_ERR, msg)
syslog.closelog()
if also_print_to_console:
click.echo(msg)
restful_logger_path = "/var/log/bmc_restful.log"
def bmc_restful_logger(message):
if not os.path.isfile(restful_logger_path):
cmd = "sudo touch %s && sudo chmod +x %s" % (
restful_logger_path, restful_logger_path)
subprocess.Popen(
shlex.split(cmd), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
logging.basicConfig(filename=restful_logger_path,
filemode='a',
format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
datefmt='%H:%M:%S',
level=logging.INFO)
logging.info(message)

View File

@ -1,304 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import shlex
import datetime
import os
import ssl
import subprocess
import syslog
class Redfish_Api():
BmcBaseUrl = 'http://240.1.1.1:8080'
ThermalUrl = '/redfish/v1/Chassis/1/Thermal'
PowerUrl = '/redfish/v1/Chassis/1/Power'
ThresholdSensorsUrl = '/redfish/v1/Chassis/1/ThresholdSensors'
FanSpeedUrl = '/redfish/v1/Chassis/1/Thermal/Actions/Oem/Ragile/Fan.SetSpeed'
BoardsUrl = '/redfish/v1/Chassis/1/Boards/'
BoardLedUrl = "/redfish/v1/Chassis/1/Boards/{}/Actions/Oem/Ragile/Boards.SetLED"
# Maximum time in seconds that you allow the connection to the server to take.
connect_timeout = 30
# Maximum time in seconds that you allow the whole operation to take
operation_timeout = 300
default_prefix='/redfish/v1/'
session = None
__DEBUG__ = "N"
__DUMP_RESP__ = "N"
RST_STATUS = "status"
RST_SUCCESS = "OK"
refish_logger = None
def redfish_log_debug(self, msg):
if (self.__DEBUG__ == "Y"):
syslog.openlog("redfis_api")
syslog.syslog(syslog.LOG_DEBUG, msg)
syslog.closelog()
def redfish_log_error(self, msg):
syslog.openlog("redfish_api")
syslog.syslog(syslog.LOG_ERR, msg)
syslog.closelog()
def __init__(self):
pass
def get_full_url(self, url):
return self.BmcBaseUrl + url
def _exec_cmd(self, cmd):
self.redfish_log_debug("Cmd: %s" % cmd)
p = subprocess.Popen(shlex.split(cmd), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.wait()
self.redfish_log_debug("Cmd return: %d" % p.returncode)
str_stdout = p.stdout.read().decode('utf-8')
str_stderr = p.stderr.read().decode('utf-8')
self.redfish_log_debug("Cmd stdout: %s" % str_stdout)
if p.returncode !=0:
self.redfish_log_error("Cmd: %s, failed! error msg:%s" % (cmd, str_stderr))
return None
else:
try:
ret = json.loads(str_stdout)
return ret
except Exception as e:
self.redfish_log_error("Cmd: %s, failed! stdout msg:%s" % (cmd, str_stdout))
return None
def _redfish_get(self, url):
self.redfish_log_debug("Get info from %s." % url)
result = None
try:
cmd_get="curl --connect-timeout %d -m %d -X GET %s" % (self.connect_timeout, self.operation_timeout, self.get_full_url(url))
result = self._exec_cmd(cmd_get)
return result
except Exception as e:
self.redfish_log_error("error_message: %s" % e)
return None
def _redfish_post(self, url, playload):
self.redfish_log_debug("post url: %s" % url)
self.redfish_log_debug("Playload: %s" % playload)
playload_json = json.dumps(playload)
result = False
try:
cmd_post="curl --connect-timeout %d -m %d -X POST %s -d \'%s\'" % (self.connect_timeout, self.operation_timeout, self.get_full_url(url), playload_json)
ret_msg = self._exec_cmd(cmd_post)
if ret_msg == None:
return False
elif ret_msg["success"] == False:
redfish_log_error("Url: '%s', Playload: '%s', Bmc return failed, error_message: %s" % (url, playload_json, ret_msg["Message"]))
result = False
else:
result = True
return result
except Exception as e:
redfish_log_error("error_message: %s" % e)
return False
def get_thermal(self):
"""Get thermal info
:returns: class 'redfish.rest.v1.RestResponse' or None when failed
"""
return self._redfish_get(self.ThermalUrl)
def get_power(self):
"""Get power info
:returns: class 'redfish.rest.v1.RestResponse' or None when failed
"""
return self._redfish_get(self.PowerUrl)
def get_thresholdSensors(self):
"""Get thresholdSensors info
:returns: class 'redfish.rest.v1.RestResponse' or None when failed
"""
return self._redfish_get(self.ThresholdSensorsUrl)
def post_odata(self, odata_id, playload):
"""post odata info
:params odata_id: the specified odata_id path
:type odata_id: string
:playload: info to post
:type: dictionary
:returns: True or False
"""
if odata_id is None or playload is None:
print("post failed: odata_id or playload is None")
return False
return self._redfish_post(odata_id, playload)
def get_odata(self, odata_id):
"""Get odata info
:params odata_id: the specified odata_id path
:type odata_id: string
:returns: class 'redfish.rest.v1.RestResponse' or None when failed
"""
if odata_id is None:
print("Get odata_id failed: odata_id is None")
return None
return self._redfish_get(odata_id)
def post_fanSpeed(self, playload):
"""post odata info
:playload: info to post
:type: dictionary
:returns: True or False
"""
if playload is None:
print("post failed: playload is None")
return False
return self._redfish_post(self.FanSpeedUrl, playload)
def get_board(self, board_name="indicatorboard"):
"""Get board info
:board_name: name of board, default is "indicatorboard"
:type: string
:returns: class'redfish.rest.v1.RestResponse' or None when failed
"""
if board_name is None :
print("get failed: board_name is None")
return None
return self._redfish_get(self.BoardsUrl + board_name)
def post_boardLed(self, playload, board_name="indicatorboard"):
"""post boardLed info
:board_name: name of board, default is "indicatorboard"
:type: string
:playload: info to post
:type: dictionary
:returns: True or False
"""
if board_name is None or playload is None:
print("post failed: playload is None")
return False
return self._redfish_post(self.BoardLedUrl.format(board_name), playload)
''' not supported currently
def post_thermal(self, playload):
"""post thermal info
:playload: info to post
:type: dictionary
:returns: True or False
"""
if playload is None:
print("post_thermal failed: playload is None")
return None
return self._redfish_post(self.ThermalUrl, playload)
def post_power(self, playload):
"""post power info
:playload: info to post
:type: dictionary
:returns: True or False
"""
if playload is None:
print("post_power failed: playload is None")
return None
return self._redfish_post(self.PowerUrl, playload)
def post_thresholdSensors(self, playload):
"""post thresholdSensors info
:playload: info to post
:type: dictionary
:returns: True or False
"""
if playload is None:
print("post_thresholdSensors failed: playload is None")
return None
return self._redfish_post(self.ThresholdSensorsUrl, playload)
def get_fanSpeed(self):
"""Get board led info
:returns: class'redfish.rest.v1.RestResponse' or None when failed
"""
return self._redfish_get(self.FanSpeedUrl)
def post_board(self, playload, board_name="indicatorboard"):
"""post board info
:board_name: name of board, default is "indicatorboard"
:type: string
:playload: info to post
:type: dictionary
:returns: True or False
"""
if board_name is None or playload is None:
print("post failed: playload is None")
return False
return self._redfish_post(self.BoardsUrl + board_name, playload)
def get_boardLed(self, board_name="indicatorboard"):
"""Get boardLed info
:board_name: name of board, default is "indicatorboard"
:type: string
:returns: class'redfish.rest.v1.RestResponse' or None when failed
"""
if board_name is None :
print("get failed: board_name is None")
return None
return self._redfish_get(self.BoardsUrl % board_name)
'''
'''
if __name__ == '__main__':
redfish = Redfish_Api()
### get
# boards
ret = redfish.get_board()
if ret is None:
print("get failed: board")
else:
print("get succeeded, board:%s" % ret)
ret = redfish.get_thresholdSensors()
if ret is None:
print("get failed: threshold")
else:
print("get succeeded, threshold:%s" % ret)
ret = redfish.get_power()
if ret is None:
print("get failed: power")
else:
print("get succeeded, power:%s" % ret)
ret = redfish.get_thermal()
if ret is None:
print("get failed:thermal")
else:
print("get succeeded,thermal:%s" % ret)
# get playload
resp = redfish.get_thresholdSensors()
if (resp != None):
print(resp["@odata.id"])
print(resp["@odata.type"])
print(resp["Id"])
print(resp["Name"])
else:
print("Failed: get_thresholdSensors")
### post
# fanSpeed
playload = {}
playload["FanName"] = 'Fan0'
playload["FanSpeedLevelPercents"] = "70"
print("post fanSpeed:%s" % redfish.post_fanSpeed(playload))
#{"LEDs": [{"IndicatorLEDColor": "green","LEDType": "sys"},{"IndicatorLEDColor": "off","LEDType": "pwr"},{"IndicatorLEDColor": "green","LEDType": "fan"}]}
playload = {}
led = {}
led1 = {}
led_list = []
led["IndicatorLEDColor"] = "green"
led["LEDType"] = "sys"
led1["IndicatorLEDColor"] = "off"
led1["LEDType"] = "pwr"
led_list.append(led)
led_list.append(led1)
playload["LEDs"] = led_list
# boardsLed
print("post boardLed:%s" % redfish.post_boardLed(playload))
'''

View File

@ -1,290 +0,0 @@
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import os
import re
import time
import mmap
configfile_pre = "/usr/local/bin/"
import sys
sys.path.append(configfile_pre)
from ragileconfig import *
import subprocess
import pexpect
import shlex
SYSLOG_IDENTIFIER = "UTILTOOL"
def os_system(cmd):
status, output = subprocess.getstatusoutput(cmd)
return status, output
def get_machine_info():
if not os.path.isfile('/host/machine.conf'):
return None
machine_vars = {}
with open('/host/machine.conf') as machine_file:
for line in machine_file:
tokens = line.split('=')
if len(tokens) < 2:
continue
machine_vars[tokens[0]] = tokens[1].strip()
return machine_vars
def get_platform_info(machine_info):
if machine_info != None:
if machine_info.__contains__('onie_platform'):
return machine_info['onie_platform']
elif machine_info.__contains__('aboot_platform'):
return machine_info['aboot_platform']
return None
'''
def cpld_version_restful(url):
if url == "" or len(url) <=0:
print("invalid url")
return
bmc = BMCMessage()
value = bmc.getBmcValue(url)
json_dicts=json.dumps(value,indent=4)
return json_dicts
'''
def lpc_cpld_rd(reg_addr):
try:
regaddr = 0
if type(reg_addr) == int:
regaddr = reg_addr
else:
regaddr = int(reg_addr, 16)
devfile = "/dev/lpc_cpld"
fd = os.open(devfile, os.O_RDWR|os.O_CREAT)
os.lseek(fd, regaddr, os.SEEK_SET)
str = os.read(fd, 1)
os.close(fd)
return "%02x" % ord(str)
except ValueError:
return None
except Exception as e:
print (e)
return None
def my_log(txt):
if DEBUG == True:
print ("[RAGILE]:",)
print (txt)
return
def log_os_system(cmd, show):
my_log (' Run :'+ cmd)
status, output = subprocess.getstatusoutput(cmd)
my_log (" with result :" + str(status))
my_log (" output :" + output)
if status:
log_error('Failed :%s msg:%s'%(cmd,output))
if show:
print ('Failed :'+ cmd)
return status, output
def password_command(cmd, password, exec_timeout=30):
newkey = 'continue connecting'
log_os_system("rm -rf ~/.ssh", 0)
msg = ""
try_times = 3
try_times_conter = try_times
while try_times_conter:
child = pexpect.spawn(cmd)
if try_times != try_times_conter:
time.sleep(5)
try_times_conter -= 1
try:
i = child.expect([pexpect.TIMEOUT, newkey, 'password: ',"refused",pexpect.EOF],timeout=30)
# If the login times out, print an error message and exit.
if i == 0: # Timeout
msg = 'connect to BMC timeout'
continue
# no public key
if i == 1:
child.sendline ('yes')
i = child.expect([pexpect.TIMEOUT, 'password: '],timeout=30)
if i == 0: # Timeout
msg = 'connect to BMC timeout'
continue
if i == 1:# Go below and enter the logic of the password
i = 2
if i == 2: # Enter the password
child.sendline (password)
i = child.expect([pexpect.EOF, pexpect.TIMEOUT], exec_timeout)
if i == 0:
return True,child.before
if i == 1:
msg = str(child.before)+"\nBMC run commands timeout"
return False,msg
if i == 3: # BMC Connection refused
msg = 'connect to BMC failed'
continue
if i == 4:
msg = child.before
except Exception as e:
msg = str(child.before)+"\nconnect to BMC failed"
return False,msg
def password_command_realtime(ssh_header, ssh_cmd, password,key_words, exec_timeout=30):
key_word_end = key_words.get("key_word_end")
key_word_pass = key_words.get("key_word_pass")
key_word_noshow = key_words.get("key_word_noshow")
# Prevents waiting caused by BMC restart
key_word_exit = key_words.get("key_word_exit")
if None in [key_word_end,key_word_pass]:
print ("Missing parameters")
return False
newkey = 'continue connecting'
log_os_system("rm -rf ~/.ssh", 0)
msg = ""
try_times = 3
key_word_pass_flag = False
try_times_conter = try_times
child = pexpect.spawn(ssh_header)
try:
i = child.expect([pexpect.TIMEOUT,newkey, 'password: ',"refused",pexpect.EOF],timeout=30)
# If the login times out, print an error message and exit.
if i == 0: # Timeout
msg = 'connect to BMC timeout'
# no public key
if i == 1:
child.sendline ('yes')
i = child.expect([pexpect.TIMEOUT, 'password: '],timeout=30)
if i == 0: # Timeout
msg = 'connect to BMC timeout'
if i == 1:# Go below and enter the logic of the password
i = 2
if i == 2: # Enter the password
child.sendline (password)
i = child.expect([pexpect.EOF, "\r",pexpect.TIMEOUT], exec_timeout)
if i == 0:
print (child.before)
return key_word_pass_flag
if i == 1:
child.sendline(ssh_cmd)
# amount received is similar to root@switch2 in order to avoid misjudgment about the end of execution
usr_symble_first = True
bmc_str_tmp=""
while True:
i = child.expect([pexpect.EOF,"\r","\n",key_word_end, pexpect.TIMEOUT], exec_timeout)
if i == 0:
return key_word_pass_flag
elif i in [1,2]:
if key_word_noshow == None or key_word_noshow not in child.before:
bmc_str, times = re.subn("\r|\n","",child.before)
if len(bmc_str) > 1:
print (bmc_str)
bmc_str_tmp=bmc_str_tmp + bmc_str
# print bmc_str_tmp
# if key_word_pass in child.before:
if re.search(key_word_pass,bmc_str_tmp) != None:
key_word_pass_flag = True
if key_word_exit != None and key_word_exit in child.before:
# Give the BMC time to execute the last command
time.sleep(3)
return key_word_pass_flag
elif i == 3 :
if usr_symble_first:
usr_symble_first = False
else:
return key_word_pass_flag
if i == 3: # BMC Connection refused
msg = 'connect to BMC failed'
if i == 4:
msg = child.before
except Exception as e:
print (e)
msg = str(child.before)+"\nconnect to BMC error"
print (msg)
return False
def get_sys_execute2(cmd, key_word_pass):
# key_word_pass_flag1 = False
key_word_pass_flag = False
filename = "/tmp/diag_excute_out"
cmd = cmd + "|tee %s" % filename
p = subprocess.Popen(shlex.split(cmd), shell=False)
p.wait()
with open(filename, 'r') as f:
str1 = f.read()
if key_word_pass in str1:
key_word_pass_flag = True
# if key_word_pass_flag1 and "100%" in str1:
# key_word_pass_flag = True
log_os_system("rm %s"%filename,0)
return key_word_pass_flag
BMC_PATH = "PATH=/usr/sbin/:/bin/:/usr/bin/:/sbin"
RETURN_KEY1 = "code"
RETURN_KEY2 = "msg"
DEBUG = False
def rgi2cget(bus, devno, address):
command_line = "i2cget -f -y %d 0x%02x 0x%02x " % (bus, devno, address)
retrytime = 6
ret_t = ""
for i in range(retrytime):
ret, ret_t = os_system(command_line)
if ret == 0:
return True, ret_t
time.sleep(0.1)
return False, ret_t
def strtoint(str): # Hexadecimal string to int,"4040"/"0x4040"/"0X4040" = 16448
value = 0
rest_v = str.replace("0X", "").replace("0x", "")
for index in range(len(rest_v)):
value |= int(rest_v[index], 16) << ((len(rest_v) - index - 1) * 4)
return value
def pci_read(pcibus, slot, fn , bar, offset):
if offset % 4 != 0:
return None
filename = "/sys/bus/pci/devices/0000:%02x:%02x.%x/resource%d" % (int(pcibus), int(slot), int(fn), int(bar))
file = open(filename, "r+")
size = os.path.getsize(filename)
data = mmap.mmap(file.fileno(), size)
result = data[offset: offset + 4]
s = result[::-1]
val = 0
for i in range(0, len(s)):
val = val << 8 | ord(s[i])
data.close()
file.close()
return val
###########################################
# Run the DMI command to obtain the BIOS information
###########################################
def getDmiSysByType(type_t):
ret, log = os_system("which dmidecode ")
if ret != 0 or len(log) <= 0:
error = "cmd find dmidecode"
return False, error
cmd = log + " -t %s" % type_t
# Get the total first
ret1, log1 = os_system(cmd)
if ret != 0 or len(log1) <= 0:
return False, "Command error[%s]" % cmd
its = log1.replace("\t", "").strip().split("\n")
ret = {}
for it in its:
if ":" in it:
key = it.split(":")[0].lstrip()
value = it.split(":")[1].lstrip()
ret[key] = value
return True, ret

Some files were not shown because too many files have changed in this diff Show More