diff --git a/README.md b/README.md index 03a7338..041745c 100644 --- a/README.md +++ b/README.md @@ -150,9 +150,11 @@ The rack front, drawn from the rack units set on cutsheet items, top first. and facing. - **Shelves to scale**: a shelf draws its contents left to right by **Position on shelf**, at true scale (a 19" panel is 482.6 mm). Gear with a drawing, such as the IceWhale ZimaBoard 832 (traced from - IceWhale's labelled photo of its port end), shows its real ports: each RJ45's link light follows the - host's physical NICs in name order (first NIC on the left jack), and the status glow follows the - host. Anything else is a labelled box. + IceWhale's labelled photo of its port end), shows its real ports: the onboard RJ45 link lights follow + enp2s0 (left) and enp3s0 (right), and the status glow follows the host. The "ZimaBoard 832 + + ConnectX-3" drawing adds the single-port SFP+ card lying flat in the side PCIe slot, as in the rack, + with a DAC attached; its round dot is Gandalf's link mark for enp1s0 (the slot is PCI bus 1), not an + LED on the card. Anything else is a labelled box. - **Racks**: admins name a rack and set its height with **Rack settings** on the page, and add more with **+ Rack** (a tab per rack). Renaming a rack moves its items; an empty rack can be deleted. Each item has a rack (empty means the first). Until a rack is saved, racks come from config: diff --git a/cutsheet.py b/cutsheet.py index d471e9d..052679b 100644 --- a/cutsheet.py +++ b/cutsheet.py @@ -38,6 +38,7 @@ CHASSIS = { 'sliger-cx4712': 'Sliger CX4712 4U (10-bay)', 'rosewill-rsv-l4500u': 'Rosewill RSV-L4500U 4U (15-bay)', 'zimaboard-832': 'IceWhale ZimaBoard 832 (shelf gear)', + 'zimaboard-832-cx3': 'IceWhale ZimaBoard 832 + ConnectX-3 SFP+ in PCIe (shelf gear)', 'server-1u': 'Generic 1U server', 'server-2u': 'Generic 2U server', 'server-4u': 'Generic 4U server', diff --git a/static/fronts.js b/static/fronts.js index 499984d..48951b2 100644 --- a/static/fronts.js +++ b/static/fronts.js @@ -172,10 +172,18 @@ function zimaUsb(x, y) { ${Array.from({ length: 5 }, (_, i) => ``).join('')}`; } +// Which NIC is which on a ZimaBoard: the onboard Realtek GbE ports enumerate on PCI buses 2 and 3 +// (enp2s0 left jack, enp3s0 right), and a card in the PCIe slot on bus 1 (enp1s0, enp1s0d1). +const ZIMA_NICS = { rj45: ['enp2s0', 'enp3s0'], slot: /^enp1s0/ }; + +function zimaNic(ctx, name) { + const n = (ctx.interfaces || []).find(i => i.name === name); + return n ? n.up : ctx.status === 'up'; +} + function zimaFront(ctx) { - // ctx: { status, interfaces: [{name, up}] } - one RJ45 per NIC, left to right - const nics = ctx.interfaces || []; - const link = i => (nics[i] ? nics[i].up : ctx.status === 'up'); + // ctx: { status, interfaces: [{name, up}] } + const link = i => zimaNic(ctx, ZIMA_NICS.rj45[i]); const on = ctx.status === 'up' || ctx.status === 'degraded'; const pads = [60, 105, 420, 470, 640, 700, 790, 835] .map(x => ``).join(''); @@ -199,10 +207,47 @@ function zimaFront(ctx) { `; } +// A Mellanox ConnectX-3 single-port SFP+ card (MCX311A) in the ZimaBoard's side PCIe slot, lying flat +// beside the board as in the rack photo (wiki.lotusguild.org/zimaboards.jpg): its front edge is about +// 54 mm (572 px at the ZimaBoard photo's 10.59 px/mm), PCB at the board's PCB height, heatsink on the +// chip, and the SFP+ cage toward the board with a DAC plugged in and its pull tab hanging down. +// The round dot on the cage is Gandalf's link mark (like the cutsheet marks), not an LED on the card. +const CX3_PX = 572; + +function cx3Card(up) { + return ` + + + + + + + ${Array.from({ length: 9 }, (_, i) => ``).join('')} + + + + + + + Gandalf: SFP+ link ${up ? 'up' : 'down'}`; +} + +function zimaCx3Front(ctx) { + return `${cx3Card(zimaNic(ctx, (ctx.interfaces || []).map(i => i.name).find(n => ZIMA_NICS.slot.test(n)) || 'enp1s0'))} + ${zimaFront(ctx)}`; +} + +const ZIMA_SPECS = 'Intel Celeron N3450, 8GB LPDDR4, 32GB eMMC, 2x GbE, 2x USB 3.0, 2x SATA, PCIe 2.0 x4, 6W'; + const SHELF_GEAR = { 'zimaboard-832': { label: 'IceWhale ZimaBoard 832', mm: ZIMA.mm, width: ZIMA.width, height: ZIMA.height, draw: zimaFront, - specs: 'Intel Celeron N3450, 8GB LPDDR4, 32GB eMMC, 2x GbE, 2x USB 3.0, 2x SATA, PCIe 2.0 x4, 6W', + specs: ZIMA_SPECS, + }, + 'zimaboard-832-cx3': { + label: 'IceWhale ZimaBoard 832 + ConnectX-3 SFP+', mm: ZIMA.mm * (ZIMA.width + CX3_PX) / ZIMA.width, + width: ZIMA.width + CX3_PX, height: ZIMA.height, draw: zimaCx3Front, + specs: `${ZIMA_SPECS}; Mellanox ConnectX-3 10G SFP+ (enp1s0) in the PCIe slot, DAC attached`, }, }; diff --git a/static/style.css b/static/style.css index 90020a6..1391918 100644 --- a/static/style.css +++ b/static/style.css @@ -1617,3 +1617,15 @@ body.fp-marks-off .fp-svg .fp-mark { display: none; } .zb-dc-face { fill: #2b2b2b; } .zb-dc-ring { fill: #4b4b4b; } .zb-dc-pin { fill: #c9a43a; } +.cx-pcb { fill: #1d6b43; } +.cx-pcb-edge { fill: #2f8a5a; } +.cx-part { fill: #26292d; } +.cx-heatsink { fill: #18191b; } +.cx-fin { fill: #2c2e31; } +.cx-cage { fill: #c8cbcf; stroke: #85898f; stroke-width: 3; } +.cx-cage-lip { fill: #dde0e3; } +.cx-plug { fill: #2b2e33; } +.cx-boot { fill: #1b1d20; } +.cx-cable { fill: #0e0f10; } +.cx-tab { fill: none; stroke: #c9ccd0; stroke-width: 9; stroke-linejoin: round; } +.cx-link { stroke: #101418; stroke-width: 3; }