2
* Copyright (c) 2004 Mellanox Technologies LTD. All rights reserved.
4
* This software is available to you under a choice of one of two
5
* licenses. You may choose to be licensed under the terms of the GNU
6
* General Public License (GPL) Version 2, available from the file
7
* COPYING in the main directory of this source tree, or the
8
* OpenIB.org BSD license below:
10
* Redistribution and use in source and binary forms, with or
11
* without modification, are permitted provided that the following
14
* - Redistributions of source code must retain the above
15
* copyright notice, this list of conditions and the following
18
* - Redistributions in binary form must reproduce the above
19
* copyright notice, this list of conditions and the following
20
* disclaimer in the documentation and/or other materials
21
* provided with the distribution.
23
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37
* IB Subnet Manager Agent Simulator object
40
* The simulator routes mad messages to the target node. This node
41
* MadProcessor SMA class is provided to handle and respond to these mads.
44
* Nimrod Gindi, Mellanox
59
#define TAVOR_DEVID 23108
60
#define ARBEL_DEVID 25208
61
#define ANAFA_DEVID 43132
62
#define ANAFA2_DEVID 47396
66
IN const ibms_mad_msg_t &madMsg,
71
MSGREG(inf100, 'M', "\n Received Mad Dump\n$", "ibms_dump_mad");
72
MSGSND(inf100, ibms_get_mad_header_str(madMsg.header));
76
MSGREG(inf101, 'M', "\n Send Mad Dump\n$", "ibms_dump_mad");
77
MSGSND(inf101, ibms_get_mad_header_str(madMsg.header));
80
switch (madMsg.header.attr_id) {
81
case IB_MAD_ATTR_PORT_INFO:
82
MSGREG(inf102, 'M', "\n Port Info Dump\n$", "ibms_dump_mad");
83
MSGSND(inf102, ibms_get_port_info_str((ib_port_info_t*)((ib_smp_t*) &madMsg.header)->data));
85
case IB_MAD_ATTR_NODE_INFO:
86
MSGREG(inf103, 'M', "\n Node Info Dump\n$", "ibms_dump_mad");
87
MSGSND(inf103, ibms_get_node_info_str((ib_node_info_t*)((ib_smp_t*) &madMsg.header)->data));
90
MSGREG(warn1, 'W', "No handler written yet for this attribute:$", "ibms_dump_mad");
92
MSGSND(warn1, cl_ntoh16(madMsg.header.attr_id));
99
SMATimer::SMATimer(int t):time(t)
101
pthread_mutex_init(&timerMutex, NULL);
102
tid = pthread_create(&th, NULL, SMATimer::timerRun, this);
104
MSGREG(err0, 'E', "Couldn't create timer thread $ !", "processMad");
107
MSGREG(inf1, 'V', "SMA timer on!", "processMad");
111
void SMATimer::terminate()
116
void* SMATimer::timerRun(void* p)
118
SMATimer* p_timer = (SMATimer*) p;
120
MSGREG(inf1, 'V', "Sleeping for $ secs !", "processMad");
121
MSGSND(inf1,p_timer->time);
123
sleep(p_timer->time);
124
pthread_mutex_lock(&p_timer->timerMutex);
126
while (i<p_timer->L.size()) {
127
int res = p_timer->L[i].f(p_timer->L[i].data);
129
p_timer->L.erase(p_timer->L.begin()+i);
133
pthread_mutex_unlock(&p_timer->timerMutex);
137
void SMATimer::reg (reg_t r)
139
pthread_mutex_lock(&timerMutex);
141
pthread_mutex_unlock(&timerMutex);
144
void SMATimer::unreg (void* data)
146
pthread_mutex_lock(&timerMutex);
147
for (unsigned i=0;i<L.size();i++)
148
if (L[i].data == data) {
149
L.erase(L.begin()+i);
152
pthread_mutex_unlock(&timerMutex);
157
SMATimer IBMSSma::mkeyTimer = SMATimer(T_FREQ);
159
int IBMSSma::cbMkey(void* data)
161
portTiming* pT = (portTiming*) data;
162
pthread_mutex_lock(&pT->mut);
164
if (pT->counter > 0) {
165
pthread_mutex_unlock(&pT->mut);
168
// Need to zero m_key
169
pT->pInfo->m_key = 0;
171
pthread_mutex_unlock(&pT->mut);
176
void IBMSSma::initSwitchInfo()
180
pNodeData = pSimNode->getIBNode();
182
pSimNode->switchInfo.lin_cap = CL_HTON16(0xbfff);
183
pSimNode->switchInfo.rand_cap = 0;
184
pSimNode->switchInfo.mcast_cap = CL_HTON16(0x1ff);
186
pSimNode->switchInfo.lin_top = 0;
187
pSimNode->switchInfo.def_port = 0;
188
pSimNode->switchInfo.def_mcast_pri_port = 0;
189
pSimNode->switchInfo.def_mcast_not_port = 0;
190
pSimNode->switchInfo.life_state = 0;
191
pSimNode->switchInfo.lids_per_port = 0;
192
pSimNode->switchInfo.enforce_cap = CL_HTON16(32);
193
pSimNode->switchInfo.flags = 0xA0; // capable partition enforce in/out
195
MSGREG(inf1, 'V', "Initialization of node's SwitchInfo is Done !", "initSwitchInfo");
197
pSimNode->sl2VlInPortEntry.resize((pSimNode->nodeInfo.num_ports) + 1);
198
initSwitchSl2VlTable();
201
void IBMSSma::initNodeInfo()
205
pNodeData = pSimNode->getIBNode();
206
pSimNode->nodeInfo.base_version = 1 ;
207
pSimNode->nodeInfo.class_version = 1 ;
208
pSimNode->nodeInfo.num_ports = pNodeData->numPorts;
210
// HACK: as the devId is not really meaningful due to IBDM limitation
211
// we only rely on the type of device. HCAs get 64 PKeys switches: 24.
212
if (pNodeData->type == 1)
215
pSimNode->nodeInfo.node_type = IB_NODE_TYPE_SWITCH;
216
pSimNode->nodeInfo.partition_cap = CL_HTON16(24);
219
else if (pNodeData->type == 2)
222
pSimNode->nodeInfo.node_type = IB_NODE_TYPE_CA;
223
pSimNode->sl2VlInPortEntry.resize((pSimNode->nodeInfo.num_ports) + 1);
224
pSimNode->nodeInfo.partition_cap = CL_HTON16(0x40);
229
MSGREG(err0, 'E', "Node Type is un-known $ !", "initNodeInfo");
230
MSGSND(err0, pNodeData->type);
232
pSimNode->nodeInfo.sys_guid = cl_hton64(pNodeData->guid_get());
233
pSimNode->nodeInfo.node_guid = pSimNode->nodeInfo.sys_guid;
234
pSimNode->nodeInfo.port_guid = pSimNode->nodeInfo.sys_guid;
236
pSimNode->nodeInfo.device_id = cl_hton16(pNodeData->devId);
237
pSimNode->nodeInfo.revision = cl_hton32(pNodeData->revId);
239
uint32_t tmpVendorLocalPort;
240
tmpVendorLocalPort = pNodeData->vendId | (1 << 24);
241
pSimNode->nodeInfo.port_num_vendor_id = cl_hton32(tmpVendorLocalPort);
243
MSGREG(inf1, 'V', "Initialization of node's NodeInfo is Done !", "initNodeInfo");
247
void IBMSSma::initPKeyTables()
250
/* initialize pkeys */
251
ib_pkey_table_t zeroPKeys;
252
ib_pkey_table_t firstBlockPkeys;
253
memset(&zeroPKeys, 0, sizeof(ib_pkey_table_t));
254
memset(&firstBlockPkeys, 0, sizeof(ib_pkey_table_t));
255
firstBlockPkeys.pkey_entry[0] = 0xffff;
257
unsigned int numBlocks;
258
vector< ib_pkey_table_t > emptyPkeyVector;
260
for (unsigned int pn = 0; pn <= pSimNode->nodeInfo.num_ports; pn++)
262
pSimNode->nodePortPKeyTable.push_back(emptyPkeyVector);
263
if ( (pSimNode->nodeInfo.node_type != IB_NODE_TYPE_SWITCH) || (pn == 0) )
264
numBlocks = (cl_ntoh16(pSimNode->nodeInfo.partition_cap) + 31) / 32;
266
numBlocks = (cl_ntoh16(pSimNode->switchInfo.enforce_cap) + 31) / 32;
268
for (unsigned int block = 0; block < numBlocks; block++)
272
pSimNode->nodePortPKeyTable[pn].push_back(zeroPKeys);
276
pSimNode->nodePortPKeyTable[pn].push_back(firstBlockPkeys);
282
void IBMSSma::initVlArbitTable()
285
ib_vl_arb_table_t vlArbitEntry;
287
for (i=0; i <= (pSimNode->nodeInfo.num_ports) ; i++)
289
//TODO when supporting enhanced port0 - will need to support 0 here as well
290
// Zero is dummy for the moment
291
for (j=0; j <= 4 ; j++)
293
for (k=0; k < IB_NUM_VL_ARB_ELEMENTS_IN_BLOCK ; k++)
295
vlArbitEntry.vl_entry[k].vl = k % IB_MAX_NUM_VLS;
296
vlArbitEntry.vl_entry[k].weight = 1;
298
(pSimNode->vlArbPortEntry[i]).push_back( vlArbitEntry );
302
MSGREG(inf1, 'V', "Initialization of VL arbitration table is Done !", "initVlArbitTable");
306
void IBMSSma::initSwitchSl2VlTable()
309
ib_slvl_table_t slToVlEntry;
311
for (i=0; i <= (pSimNode->nodeInfo.num_ports) ; i++)
313
//TODO when supporting enhanced port0 - will need to support 0 here as well
314
// Zero is dummy for the moment
315
for (j=0; j <= (pSimNode->nodeInfo.num_ports) ; j++)
317
for (k=0; k < (IB_MAX_NUM_VLS/2) ; k++)
319
slToVlEntry.raw_vl_by_sl[k] = 0xf;
321
(pSimNode->sl2VlInPortEntry[i]).push_back( slToVlEntry );
325
MSGREG(inf1, 'V', "Initialization of switch SL to VL table is Done !", "initSwitchSl2VlTable");
329
void IBMSSma::initCaSl2VlTable()
332
ib_slvl_table_t slToVlEntry;
334
for (i=0; i <= (pSimNode->nodeInfo.num_ports) ; i++)
336
for (k=0; k < (IB_MAX_NUM_VLS/2) ; k++)
338
slToVlEntry.raw_vl_by_sl[k] = 0xf;
340
(pSimNode->sl2VlInPortEntry[i]).push_back( slToVlEntry );
343
MSGREG(inf1, 'V', "Initialization of CA SL to VL table is Done !", "initCaSl2VlTable");
347
void IBMSSma::initPortInfo()
352
ib_port_info_t tmpPortInfo;
353
IBPort *pNodePortData;
356
pNodeData = pSimNode->getIBNode();
358
memset((void*)&tmpPortInfo, 0, sizeof(ib_port_info_t));
359
if (pSimNode->nodeInfo.node_type == IB_NODE_TYPE_CA)
361
MSGREG(inf1, 'V', "Creating dummy port number $ for xCA !", "initPortInfo");
364
else if (pSimNode->nodeInfo.node_type == IB_NODE_TYPE_SWITCH)
366
// TODO add Enhanced Port Zero support
367
MSGREG(inf2, 'V', "Creating Base port Zero for Switch !", "initPortInfo");
370
//Init the port 0 of the switch according to it's capability
371
tmpPortInfo.capability_mask = CL_HTON32(0x808);
372
ib_port_info_set_lmc(&tmpPortInfo, 0);
373
ib_port_info_set_mpb(&tmpPortInfo, 0);
374
//we do not have to support this ! (HACK: Done to avoid OSM bugs)
375
// Base Port 0 case we need mtu_cap too:
376
tmpPortInfo.mtu_cap = 1;
377
ib_port_info_set_neighbor_mtu(&tmpPortInfo, 1);
378
ib_port_info_set_vl_cap(&tmpPortInfo, 4);
379
ib_port_info_set_port_state( &tmpPortInfo, IB_LINK_ACTIVE);
380
ib_port_info_set_port_phys_state( 5, &tmpPortInfo);
382
tmpPortInfo.subnet_timeout = 0;
383
tmpPortInfo.resp_time_value = 0x6;
388
MSGREG(err0, 'E', "Attempt to initialize unknown device port !", "initPortInfo");
393
pSimNode->nodePortsInfo.push_back( tmpPortInfo );
396
while (i <= pSimNode->nodeInfo.num_ports)
398
MSGREG(inf1, 'V', "Initializing port number $ !", "initPortInfo");
401
memset((void*)&tmpPortInfo, 0, sizeof(ib_port_info_t));
402
pNodePortData = pNodeData->getPort(i);
403
if ((pNodePortData == NULL) || (pNodePortData->p_remotePort == NULL))
405
MSGREG(wrn0, 'W', "Attempt to reach port $ failed - no such port OR it's not connected!", "initPortInfo");
407
MSGREG(wrn1, 'W', " Entering dummy entry !", "initPortInfo");
409
//TODO handle not connected port generic - remove all assignments from below
410
ib_port_info_set_port_state( &tmpPortInfo, IB_LINK_DOWN);
411
ib_port_info_set_port_phys_state( 2, &tmpPortInfo);
412
pSimNode->nodePortsInfo.push_back( tmpPortInfo );
417
tmpPortInfo.base_lid = cl_hton16(pNodePortData->base_lid);
418
tmpPortInfo.capability_mask = CL_HTON32(0x808);
419
tmpPortInfo.local_port_num = i;
420
tmpPortInfo.link_width_enabled = pNodePortData->width;
421
tmpPortInfo.link_width_supported = pNodePortData->width;
422
tmpPortInfo.link_width_active = pNodePortData->width;
424
int linkSpeed = pNodePortData->speed;
426
if (pNodePortData->speed == 2)
430
else if (pNodePortData->speed == 4)
434
// LinkSpeedSupported and PortState
435
ib_port_info_set_port_state( &tmpPortInfo, IB_LINK_INIT);
436
ib_port_info_set_link_speed_sup( linkSpeed, &tmpPortInfo);
437
// LinkSpeedEnabled and LinkSpeedActive
438
tmpPortInfo.link_speed = linkSpeed | (pNodePortData->speed << 4);
442
// PortPhysState and LinkDownDefaultState
443
ib_port_info_set_port_phys_state( 5, &tmpPortInfo);
444
ib_port_info_set_link_down_def_state( &tmpPortInfo, 2);
445
tmpPortInfo.mtu_smsl = 1;
446
ib_port_info_set_neighbor_mtu( &tmpPortInfo, 4);
447
ib_port_info_set_vl_cap(&tmpPortInfo, 4);
448
tmpPortInfo.vl_high_limit = 1;
449
tmpPortInfo.vl_arb_high_cap = 8;
450
tmpPortInfo.vl_arb_low_cap = 8;
451
tmpPortInfo.mtu_cap = 4;
452
tmpPortInfo.guid_cap = 32;
453
tmpPortInfo.resp_time_value = 20;
455
pSimNode->nodePortsInfo.push_back( tmpPortInfo );
463
IBMSSma::IBMSSma(IBMSNode *pSNode, list_uint16 mgtClasses) :
464
IBMSMadProcessor(pSNode, mgtClasses)
470
pNodeData = pSNode->getIBNode();
471
//Init NodeInfo structure of the node
473
//Init P_Key ports vector size
474
pSimNode->nodePortPKeyTable.resize(pSimNode->nodeInfo.num_ports + 1);
475
//Init PortInfo structure of the node + Init P_Key Tables of ports
477
//Init VL Arbitration ports vector size and table
478
pSimNode->vlArbPortEntry.resize(pSimNode->nodeInfo.num_ports + 1);
479
//Init ports' timing vector
480
vPT.resize(pSimNode->nodeInfo.num_ports + 1);
481
for (unsigned i=0;i<vPT.size();i++)
482
if ((pSimNode->nodeInfo.node_type == IB_NODE_TYPE_SWITCH) || i!=0) {
483
vPT[i].pInfo = &(pSimNode->nodePortsInfo[i]);
484
pthread_mutex_init(&vPT[i].mut, NULL);
494
//--------------------------------------------------------------------------------
495
//--------------------------------------------------------------------------------
496
//--------------------------------------------------------------------------------
498
int IBMSSma::nodeDescMad(ibms_mad_msg_t &respMadMsg)
504
MSGREG(inf1, 'I', "NodeDescription Get mad handling !", "nodeDescMad");
506
pRespMad = (ib_smp_t*) &respMadMsg.header;
509
if (pSimNode->nodeInfo.node_type != 2)
511
desc = (pSimNode->getIBNode())->p_system->name + string(" HCA-1 (Mellanox HCA)");
515
desc = (pSimNode->getIBNode())->p_system->name + string(" Infiniscale-III Mellanox Technologies");
518
int descLen = desc.size();
519
if (descLen > 64) descLen = 64;
520
memcpy(pRespMad->data, desc.c_str(), descLen);
521
if (descLen < 64) pRespMad->data[descLen] = 0;
526
int IBMSSma::nodeInfoMad(ibms_mad_msg_t &respMadMsg, uint8_t inPort)
532
MSGREG(inf1, 'I', "NodeInfo Get mad handling !", "nodeInfoMad");
534
pRespMad = (ib_smp_t*) &respMadMsg.header;
535
ib_node_info_set_local_port_num( &(pSimNode->nodeInfo), inPort);
536
memcpy (pRespMad->data, &(pSimNode->nodeInfo), sizeof(pSimNode->nodeInfo));
538
/* provide the port guid for CA ports */
539
if (pSimNode->nodeInfo.node_type != 2)
541
ib_node_info_t *p_node_info = (ib_node_info_t *)pRespMad->data;
542
IBPort *pPort = pSimNode->getIBNode()->getPort(inPort);
544
p_node_info->port_guid = cl_hton64(pPort->guid_get());
551
int IBMSSma::lftMad(ibms_mad_msg_t &respMadMsg, ibms_mad_msg_t &reqMadMsg)
555
ib_net16_t status = 0;
557
uint8_t lftBlock[64];
558
uint32_t lftIndex = 0;
561
pRespMad = (ib_smp_t*) &respMadMsg.header;
563
if ((uint16_t)(cl_ntoh16(pSimNode->switchInfo.lin_cap)/64) <
564
cl_ntoh32(reqMadMsg.header.attr_mod))
567
"Req. lft block is $ while SwitchInfo LFT Cap is $ !",
569
MSGSND(err0, cl_ntoh32(reqMadMsg.header.attr_mod),
570
cl_ntoh16(pSimNode->switchInfo.lin_cap));
571
status = IB_MAD_STATUS_INVALID_FIELD;
577
lftIndex = cl_ntoh32(reqMadMsg.header.attr_mod) * 64;
578
iter = cl_ntoh32(reqMadMsg.header.attr_mod);
579
MSGREG(inf3, 'V', "Linear Forwarding entry handled is $ and block number is $ ", "lftMad");
580
MSGSND(inf3, lftIndex, iter);
582
if (reqMadMsg.header.method == IB_MAD_METHOD_GET)
584
MSGREG(inf1, 'V', "LFT SubnGet !", "lftMad");
587
//copy entries from lft according to index
588
for (iter=0;iter<64;iter++) lftBlock[iter] =
589
(pSimNode->getIBNode())->getLFTPortForLid(lftIndex + iter);
593
MSGREG(inf2, 'V', "LFT SubnSet !", "lftMad");
596
memcpy ( &lftBlock[0], pRespMad->data, 64 * sizeof(uint8_t));
597
//copy entries from lft according to index
598
for (iter=0;iter<64;iter++)
599
(pSimNode->getIBNode())->setLFTPortForLid(lftIndex + iter, lftBlock[iter]);
602
memcpy (pRespMad->data, &lftBlock[0], 64 * sizeof(uint8_t));
608
int IBMSSma::vlArbMad(ibms_mad_msg_t &respMadMsg, ibms_mad_msg_t &reqMadMsg, uint8_t inPort)
612
ib_net16_t status = 0;
615
uint8_t portIndex, priorityIndex;
616
ib_vl_arb_table_t vlArbEntryElm;
617
ib_vl_arb_table_t* pVlArbEntryElm;
619
if (pSimNode->nodeInfo.node_type == IB_NODE_TYPE_SWITCH)
621
portIndex = (cl_ntoh32(reqMadMsg.header.attr_mod) & 0xff);
627
priorityIndex = (cl_ntoh32(reqMadMsg.header.attr_mod) >> 16);
628
if (priorityIndex == 0) {
630
"Req. blockIndex is $ legal values are 1..4 !",
632
MSGSND(err0, portIndex, pSimNode->nodeInfo.num_ports);
633
status = IB_MAD_STATUS_INVALID_FIELD;
638
if (portIndex > pSimNode->nodeInfo.num_ports)
641
"Req. port is $ while Node number of ports is $ !",
643
MSGSND(err1, portIndex, pSimNode->nodeInfo.num_ports);
644
status = IB_MAD_STATUS_INVALID_FIELD;
649
pRespMad = (ib_smp_t*) &respMadMsg.header;
650
pReqMad = (ib_smp_t*) &reqMadMsg.header;
652
MSGREG(inf0, 'V', "VL Arbitration entry handled for port $ and priority $ ", "vlArbMad");
653
MSGSND(inf0, portIndex, priorityIndex);
655
if (reqMadMsg.header.method == IB_MAD_METHOD_GET)
657
MSGREG(inf1, 'V', "VL Arbitration SubnGet !", "vlArbMad");
660
vlArbEntryElm = (pSimNode->vlArbPortEntry[portIndex])[priorityIndex];
661
memcpy ((void*)(pRespMad->data), (void*)(&vlArbEntryElm), sizeof(ib_vl_arb_table_t));
665
MSGREG(inf2, 'V', "VL Arbitration SubnSet !", "vlArbMad");
668
pVlArbEntryElm = &(pSimNode->vlArbPortEntry[portIndex])[priorityIndex];
669
memcpy ((void*)(pVlArbEntryElm), (void*)(pReqMad->data), sizeof(ib_vl_arb_table_t));
670
memcpy ((void*)(pRespMad->data), (void*)(pReqMad->data), sizeof(ib_vl_arb_table_t));
677
int IBMSSma::sl2VlMad(ibms_mad_msg_t &respMadMsg, ibms_mad_msg_t &reqMadMsg, uint8_t inPort)
681
ib_net16_t status = 0;
684
uint8_t inputPortIndex, outputPortIndex;
685
ib_slvl_table_t sl2VlEntryElm;
686
ib_slvl_table_t* pSl2VlEntryElm;
688
if (pSimNode->nodeInfo.node_type == IB_NODE_TYPE_SWITCH)
690
inputPortIndex = ((cl_ntoh32(reqMadMsg.header.attr_mod) >> 8) & 0xff);
691
outputPortIndex = (cl_ntoh32(reqMadMsg.header.attr_mod) & 0xff);
696
outputPortIndex = inPort;
699
if ((inputPortIndex > pSimNode->nodeInfo.num_ports) ||
700
(outputPortIndex > pSimNode->nodeInfo.num_ports))
703
"Req. mft input port is $ and output port is $ while Node number of ports is $ !",
705
MSGSND(err0, inputPortIndex, outputPortIndex, pSimNode->nodeInfo.num_ports);
706
status = IB_MAD_STATUS_INVALID_FIELD;
711
pRespMad = (ib_smp_t*) &respMadMsg.header;
712
pReqMad = (ib_smp_t*) &reqMadMsg.header;
714
MSGREG(inf0, 'V', "SL2VL entry handled for input port $ and output port $ ", "sl2VlMad");
715
MSGSND(inf0, inputPortIndex, outputPortIndex);
717
if (reqMadMsg.header.method == IB_MAD_METHOD_GET)
719
MSGREG(inf1, 'V', "SL2VL SubnGet !", "sl2VlMad");
722
sl2VlEntryElm = (pSimNode->sl2VlInPortEntry[inputPortIndex])[outputPortIndex];
723
memcpy ((void*)(pRespMad->data), (void*)(&sl2VlEntryElm), sizeof(ib_slvl_table_t));
727
MSGREG(inf2, 'V', "SL2VL SubnSet !", "sl2VlMad");
730
pSl2VlEntryElm = &(pSimNode->sl2VlInPortEntry[inputPortIndex])[outputPortIndex];
731
memcpy ((void*)(pSl2VlEntryElm), (void*)(pReqMad->data), sizeof(ib_slvl_table_t));
732
memcpy ((void*)(pRespMad->data), (void*)(pReqMad->data), sizeof(ib_slvl_table_t));
739
int IBMSSma::mftMad(ibms_mad_msg_t &respMadMsg, ibms_mad_msg_t &reqMadMsg)
743
ib_net16_t status = 0;
746
uint16_t mftTableEntryIndex = (cl_ntoh32(reqMadMsg.header.attr_mod) & IB_MCAST_BLOCK_ID_MASK_HO);
747
uint8_t mftPortEntryIndex = (cl_ntoh32(reqMadMsg.header.attr_mod) >> IB_MCAST_POSITION_SHIFT);
748
ib_mft_table_t* pMftEntryElm;
750
pRespMad = (ib_smp_t*) &respMadMsg.header;
751
pReqMad = (ib_smp_t*) &reqMadMsg.header;
754
// 1. AM bits 0-8 =< SwitchInfo:MftCap
755
// 2. ((((AM bits 28-31) + 1)*16)-1) <= NodeInfo:NumberOfPort
756
if ((cl_ntoh16(pSimNode->switchInfo.mcast_cap)/IB_MCAST_BLOCK_SIZE) < mftTableEntryIndex)
759
"Req. mft entry block is $ while SwitchInfo MFT Cap is $ !",
761
MSGSND(err0, mftTableEntryIndex,
762
cl_ntoh16(pSimNode->switchInfo.mcast_cap));
763
status = IB_MAD_STATUS_INVALID_FIELD;
768
if (mftPortEntryIndex * 16 > pSimNode->nodeInfo.num_ports)
771
"Req. mft port block is $ while NodeInfo number of ports is $ !",
773
MSGSND(err1, mftPortEntryIndex, pSimNode->nodeInfo.num_ports);
774
status = IB_MAD_STATUS_INVALID_FIELD;
780
MSGREG(inf3, 'E', "Multicast Forwarding entry handled portIdx $ blockIdx $ ", "mftMad");
781
MSGSND(inf3, mftTableEntryIndex, mftPortEntryIndex);
783
if (reqMadMsg.header.method == IB_MAD_METHOD_GET)
785
MSGREG(inf1, 'V', "MFT SubnGet !", "mftMad");
788
if ( (mftPortEntryIndex >= pSimNode->switchMftPortsEntry.size()) ||
789
(mftTableEntryIndex >= pSimNode->switchMftPortsEntry[mftPortEntryIndex].size()))
791
MSGREG(warn1, 'W', "MFT SubnGet with uninitialized values at portIdx:$ blockIdx:$ !", "mftMad");
792
MSGSND(warn1,mftPortEntryIndex, mftTableEntryIndex);
793
memset ((void*)(pRespMad->data), 0, sizeof(ib_mft_table_t));
798
pMftEntryElm = &(pSimNode->switchMftPortsEntry[mftPortEntryIndex][mftTableEntryIndex]);
799
memcpy ((void*)(pRespMad->data), (void*)(pMftEntryElm), sizeof(ib_mft_table_t));
804
MSGREG(inf2, 'V', "MFT SubnSet !", "mftMad");
807
MSGREG(inf9, 'E', "MFT SubnSet $ base_port:$ block:$ entry 0 value:$", "mftMad");
809
for (i = pSimNode->switchMftPortsEntry.size(); i <= mftPortEntryIndex; i++)
811
vector < ib_mft_table_t > tmpVec;
812
pSimNode->switchMftPortsEntry.push_back(tmpVec);
815
for (i = pSimNode->switchMftPortsEntry[mftPortEntryIndex].size(); i <= mftTableEntryIndex; i++)
818
memset(&tmp, 0, sizeof(ib_mft_table_t));
819
pSimNode->switchMftPortsEntry[mftPortEntryIndex].push_back(tmp);
822
pMftEntryElm = &(pSimNode->switchMftPortsEntry[mftPortEntryIndex][mftTableEntryIndex]);
823
memcpy ((void*)(pMftEntryElm), (void*)(pReqMad->data), sizeof(ib_mft_table_t));
825
sprintf(buff,"0x%04x", cl_ntoh16(pMftEntryElm->mft_entry[0]));
826
MSGSND(inf9, pSimNode->getIBNode()->name,
827
mftPortEntryIndex, mftTableEntryIndex, buff);
828
memcpy ((void*)(pRespMad->data), (void*)(pReqMad->data), sizeof(ib_mft_table_t));
835
int IBMSSma::switchInfoMad(ibms_mad_msg_t &respMadMsg, ibms_mad_msg_t &reqMadMsg)
839
ib_net16_t status = 0;
842
pRespMad = (ib_smp_t*) &respMadMsg.header;
844
if (reqMadMsg.header.method == IB_MAD_METHOD_GET)
846
MSGREG(inf2, 'V', "SwitchInfo SubnGet !", "switchInfoMad");
851
MSGREG(inf3, 'V', "SwitchInfo SubnSet !", "switchInfoMad");
855
ib_switch_info_t* pReqSwitchInfo;
857
pReqMad = (ib_smp_t*) &reqMadMsg.header;
858
pReqSwitchInfo = (ib_switch_info_t*)(pReqMad->data);
860
if (cl_ntoh16(pReqSwitchInfo->lin_top) >= cl_ntoh16(pSimNode->switchInfo.lin_cap))
863
"SwitchInfo LFT Cap is $ and lower from req. LFT Top $ !",
865
MSGSND(err0, cl_ntoh16(pSimNode->switchInfo.lin_cap),
866
cl_ntoh16(pReqSwitchInfo->lin_top));
867
status = IB_MAD_STATUS_INVALID_FIELD;
873
pSimNode->switchInfo.lin_top = pReqSwitchInfo->lin_top;
874
pSimNode->switchInfo.def_port = pReqSwitchInfo->def_port;
875
pSimNode->switchInfo.def_mcast_pri_port = pReqSwitchInfo->def_mcast_pri_port;
876
pSimNode->switchInfo.def_mcast_not_port = pReqSwitchInfo->def_mcast_not_port;
878
if (ib_switch_info_get_state_change(pReqSwitchInfo))
880
ib_switch_info_clear_state_change(pReqSwitchInfo);
884
if (ib_switch_info_get_state_change(&(pSimNode->switchInfo)))
885
ib_switch_info_set_state_change(pReqSwitchInfo);
887
pSimNode->switchInfo.life_state = pReqSwitchInfo->life_state;
891
memcpy (pRespMad->data, &(pSimNode->switchInfo), sizeof(ib_switch_info_t));
897
int IBMSSma::setPortInfoGeneral(ibms_mad_msg_t &respMadMsg,
898
ibms_mad_msg_t &reqMadMsg,
900
ib_port_info_t portInfoElm,
904
ib_net16_t status = 0;
906
ib_port_info_t* pReqPortInfo;
907
ib_port_info_t* pNodePortInfo;
909
pReqMad = (ib_smp_t*) &reqMadMsg.header;
910
pReqPortInfo = (ib_port_info_t*)(pReqMad->data);
911
pNodePortInfo = &(pSimNode->nodePortsInfo[portNum]);
913
if (ib_port_info_get_port_state(&portInfoElm) == IB_LINK_DOWN)
915
MSGREG(err0, 'W', "PortInfo PortState is Down - Port Not connected !", "setPortInfoGeneral");
917
status = IB_MAD_STATUS_INVALID_FIELD;
923
pNodePortInfo->local_port_num = inPort;
924
pNodePortInfo->m_key = pReqPortInfo->m_key;
925
pNodePortInfo->subnet_prefix = pReqPortInfo->subnet_prefix;
927
pNodePortInfo->m_key_lease_period = pReqPortInfo->m_key_lease_period;
928
// TODO: check LinkWidthEnabled parameter from the SM (check very complexed)
929
if (pReqPortInfo->link_width_enabled)
931
pNodePortInfo->link_width_enabled = pReqPortInfo->link_width_enabled;
935
// state_info1 == LinkSpeedSupported and PortState
936
uint8_t newPortState;
937
uint8_t oldPortState;
939
newPortState = ib_port_info_get_port_state(pReqPortInfo);
940
oldPortState = ib_port_info_get_port_state(pNodePortInfo);
941
if (((newPortState == IB_LINK_INIT) || (newPortState >= IB_LINK_ACT_DEFER)) ||
942
((oldPortState == IB_LINK_DOWN) &&
943
((newPortState == IB_LINK_ARMED) || (newPortState == IB_LINK_ACTIVE))) ||
944
((oldPortState == IB_LINK_ARMED) && (newPortState == IB_LINK_ARMED)) ||
945
((newPortState == IB_LINK_ACTIVE) &&
946
((oldPortState == IB_LINK_ACTIVE) && (newPortState == IB_LINK_INIT))))
948
MSGREG(err0, 'E', "PortInfo PortState set for $ from $ is invalid !", "setPortInfoGeneral");
949
MSGSND(err0, newPortState, oldPortState);
950
status = IB_MAD_STATUS_INVALID_FIELD;
956
if (newPortState == IB_LINK_DOWN) newPortState = IB_LINK_INIT;
957
// if all checks passed then set and change required
960
ib_port_info_set_port_state(pNodePortInfo, newPortState);
964
{ //state_info2 == PortPhysState and LinkDownDefaultState
965
uint8_t newPortPhyState;
966
uint8_t newDefDownPortState;
968
newPortPhyState = ib_port_info_get_port_phys_state(pReqPortInfo);
969
if (newPortPhyState >= 4)
971
MSGREG(err1, 'E', "PortInfo PortPhyState set for $ (higher or equal to 4) !", "setPortInfoGeneral");
972
MSGSND(err1, newPortPhyState);
973
status = IB_MAD_STATUS_INVALID_FIELD;
979
newDefDownPortState = ib_port_info_get_link_down_def_state(pReqPortInfo);
980
if (newDefDownPortState >= 3)
982
MSGREG(err2, 'E', "PortInfo LinkDownDefualt State set for $ (higher or equal to 3) !", "setPortInfoGeneral");
983
MSGSND(err2, newDefDownPortState);
984
status = IB_MAD_STATUS_INVALID_FIELD;
992
ib_port_info_set_port_phys_state(newPortPhyState, pNodePortInfo);
994
if (newDefDownPortState)
996
ib_port_info_set_link_down_def_state(pNodePortInfo, newDefDownPortState);
1000
{ // LinkSpeedEnabled and LinkSpeedActive
1001
uint8_t linkSpeedEn;
1003
linkSpeedEn = ib_port_info_get_link_speed_enabled(pReqPortInfo);
1004
if ((linkSpeedEn >= 8) && (linkSpeedEn <= 0xe))
1006
MSGREG(err3, 'E', "PortInfo Link speed enabled set for $ (between 0x8 and 0xe) !", "setPortInfoGeneral");
1007
MSGSND(err3, linkSpeedEn);
1008
status = IB_MAD_STATUS_INVALID_FIELD;
1015
ib_port_info_set_link_speed_enabled(pNodePortInfo, linkSpeedEn);
1017
} // END LinkSpeedEnabled and LinkSpeedActive
1019
pNodePortInfo->vl_high_limit = pReqPortInfo->vl_high_limit;
1020
pNodePortInfo->m_key_violations = pReqPortInfo->m_key_violations;
1021
pNodePortInfo->p_key_violations = pReqPortInfo->p_key_violations;
1022
pNodePortInfo->q_key_violations = pReqPortInfo->q_key_violations;
1023
pNodePortInfo->subnet_timeout = pReqPortInfo->subnet_timeout;
1024
pNodePortInfo->error_threshold = pReqPortInfo->error_threshold;
1030
/* set the IBPort base lid and keep the map of port by lid consistent */
1031
int IBMSSma::setIBPortBaseLid(
1037
IBPort* pPort = NULL;
1038
unsigned int portLidIndex;
1039
unsigned int minPortNum;
1040
unsigned int maxPortNum;
1043
MSGREG(inf0, 'I', "Setting base_lid for node:$ port:$ to $",
1044
"setIBPortBaseLid");
1045
pNode = pSimNode->getIBNode();
1048
We need a special case for switch port 0 changing
1049
the reason is that there is no IBPort since they are all physical
1050
what we do is to search for port 1 - N and set them properly.
1051
Then we find and change the port by lid table.
1053
if (pNode->type == IB_SW_NODE)
1058
maxPortNum = pNode->numPorts;
1062
MSGREG(w0, 'W', "Ignoring switch port $ != 0", "setIBPortBaseLid");
1063
MSGSND(w0, inPortNum);
1069
minPortNum = maxPortNum = inPortNum;
1072
for (unsigned int portNum = minPortNum; portNum <= maxPortNum; portNum++)
1074
pPort = pNode->getPort(portNum);
1077
MSGREG(err9, 'E', "No Port $ on node:$!", "setIBPortBaseLid");
1078
MSGSND(err9, portNum, pNode->name);
1082
MSGSND(inf0, pNode->name, portNum, base_lid);
1084
/* keep track of the previous lid */
1085
uint16_t prevLid = pPort->base_lid;
1087
/* assign the lid */
1088
pPort->base_lid = base_lid;
1090
/* make sure the vector of port by lid has enough entries */
1091
if (pNode->p_fabric->PortByLid.size() <= base_lid)
1093
/* we add 20 entries each time */
1094
pNode->p_fabric->PortByLid.resize(base_lid+20);
1095
for ( portLidIndex = pNode->p_fabric->PortByLid.size();
1096
portLidIndex < (unsigned int)(base_lid + 20);
1099
pNode->p_fabric->PortByLid[portLidIndex] = NULL;
1103
/* keep track of the max lid */
1104
if ( pNode->p_fabric->maxLid < base_lid )
1105
pNode->p_fabric->maxLid = base_lid;
1107
/* need to cleanup the previous entry */
1108
if (prevLid < pNode->p_fabric->PortByLid.size())
1109
pNode->p_fabric->PortByLid[prevLid] = NULL;
1111
/* cleanup old base_lid for ports that used to have that lid ... */
1112
IBPort *pPrevPort = pNode->p_fabric->PortByLid[base_lid];
1113
if (pPrevPort && (pPrevPort != pPort))
1115
/* for HCAs we can not have two ports pointing at the same lid */
1116
/* for switches - it must be the same switch ... */
1117
if ((pNode->type != IB_SW_NODE) || (pPrevPort->p_node != pNode))
1118
pPrevPort->base_lid = 0;
1123
/* now set the new port by lid */
1124
pNode->p_fabric->PortByLid[base_lid] = pPort;
1130
int IBMSSma::setPortInfoSwBasePort(ibms_mad_msg_t &respMadMsg,
1131
ibms_mad_msg_t &reqMadMsg,
1133
ib_port_info_t portInfoElm,
1137
ib_net16_t status = 0;
1139
ib_port_info_t* pReqPortInfo;
1140
ib_port_info_t* pNodePortInfo;
1143
pReqMad = (ib_smp_t*) &reqMadMsg.header;
1144
pReqPortInfo = (ib_port_info_t*)(pReqMad->data);
1145
pNodePortInfo = &(pSimNode->nodePortsInfo[portNum]);
1147
if ((pReqPortInfo->base_lid == 0) || (cl_ntoh16(pReqPortInfo->base_lid) >= 0xbfff))
1149
MSGREG(err6, 'E', "PortInfo Invalid Lid set to $ on SW Base port!", "setPortInfoSwBasePort");
1150
MSGSND(err6, pReqPortInfo->base_lid);
1151
status = IB_MAD_STATUS_INVALID_FIELD;
1158
/* need to update the IBPort base lid on a change */
1159
if (pNodePortInfo->base_lid != pReqPortInfo->base_lid)
1161
setIBPortBaseLid(pSimNode, portNum, cl_ntoh16(pReqPortInfo->base_lid));
1162
pNodePortInfo->base_lid = pReqPortInfo->base_lid;
1166
MSGREG(inf1, 'V', "Lid does not require change by the SubnSet !", "setPortInfoSwBasePort");
1172
if ((pReqPortInfo->master_sm_base_lid == 0) || (cl_ntoh16(pReqPortInfo->master_sm_base_lid) >= 0xbfff))
1174
MSGREG(err5, 'E', "PortInfo Invalid master SM Lid set for $ !", "setPortInfoSwBasePort");
1175
MSGSND(err5, pReqPortInfo->master_sm_base_lid);
1176
status = IB_MAD_STATUS_INVALID_FIELD;
1181
else pNodePortInfo->master_sm_base_lid = pReqPortInfo->master_sm_base_lid;
1185
uint8_t mKeyProtectBits;
1187
reqLmc = ib_port_info_get_lmc(pReqPortInfo);
1190
MSGREG(err3, 'E', "Base Port0 PortInfo LMC set for $ (must be 0) !", "setPortInfoSwBasePort");
1191
MSGSND(err3, reqLmc);
1192
status = IB_MAD_STATUS_INVALID_FIELD;
1197
ib_port_info_set_lmc(pNodePortInfo, 0);
1199
mKeyProtectBits = ib_port_info_get_mpb(pReqPortInfo);
1200
ib_port_info_set_mpb(pNodePortInfo, mKeyProtectBits);
1206
masterSmSl = ib_port_info_get_smsl(pReqPortInfo);
1207
ib_port_info_set_smsl(pNodePortInfo, masterSmSl);
1214
int IBMSSma::setPortInfoSwExtPort(ibms_mad_msg_t &respMadMsg,
1215
ibms_mad_msg_t &reqMadMsg,
1217
ib_port_info_t portInfoElm,
1221
ib_net16_t status = 0;
1223
ib_port_info_t* pReqPortInfo;
1224
ib_port_info_t* pNodePortInfo;
1226
pReqMad = (ib_smp_t*) &reqMadMsg.header;
1227
pReqPortInfo = (ib_port_info_t*)(pReqMad->data);
1228
pNodePortInfo = &(pSimNode->nodePortsInfo[portNum]);
1234
nMtuReq = ib_port_info_get_neighbor_mtu(pReqPortInfo);
1235
mtuCap = ib_port_info_get_mtu_cap(pNodePortInfo);
1236
if ((nMtuReq == 0) || (nMtuReq > 5) || (nMtuReq > mtuCap))
1238
MSGREG(err4, 'E', "PortInfo N - MTU set for $ with MTU Cap $ !", "setPortInfoSwExtPort");
1239
MSGSND(err4, nMtuReq, mtuCap);
1240
status = IB_MAD_STATUS_INVALID_FIELD;
1245
ib_port_info_set_neighbor_mtu(pNodePortInfo, nMtuReq);
1248
pNodePortInfo->vl_stall_life = pReqPortInfo->vl_stall_life;
1254
reqOpVl = ib_port_info_get_op_vls(pReqPortInfo);
1255
vlCap = ib_port_info_get_vl_cap(pNodePortInfo);
1257
if ((reqOpVl > vlCap) || (reqOpVl > 5))
1259
MSGREG(err5, 'E', "PortInfo Operational VL set for $ with VL Cap $ !", "setPortInfoSwExtPort");
1260
MSGSND(err5, reqOpVl, vlCap);
1261
status = IB_MAD_STATUS_INVALID_FIELD;
1266
if (reqOpVl) ib_port_info_set_op_vls(pNodePortInfo, reqOpVl);
1269
// TODO check if legal
1270
pNodePortInfo->vl_enforce =
1271
pNodePortInfo->vl_enforce & 0xf0 | pReqPortInfo->vl_enforce & 0xf;
1277
int IBMSSma::setPortInfoHca(ibms_mad_msg_t &respMadMsg,
1278
ibms_mad_msg_t &reqMadMsg,
1280
ib_port_info_t portInfoElm,
1284
ib_net16_t status = 0;
1286
ib_port_info_t* pReqPortInfo;
1287
ib_port_info_t* pNodePortInfo;
1289
pReqMad = (ib_smp_t*) &reqMadMsg.header;
1290
pReqPortInfo = (ib_port_info_t*)(pReqMad->data);
1291
pNodePortInfo = &(pSimNode->nodePortsInfo[portNum]);
1293
if ((pReqPortInfo->base_lid == 0) || (cl_ntoh16(pReqPortInfo->base_lid) >= 0xbfff))
1295
MSGREG(err6, 'E', "PortInfo Invalid Lid set to $ on HCA!", "setPortInfoHca");
1296
MSGSND(err6, pReqPortInfo->base_lid);
1297
status = IB_MAD_STATUS_INVALID_FIELD;
1304
if (pNodePortInfo->base_lid != pReqPortInfo->base_lid)
1306
setIBPortBaseLid(pSimNode, portNum, cl_ntoh16(pReqPortInfo->base_lid));
1307
pNodePortInfo->base_lid = pReqPortInfo->base_lid;
1311
MSGREG(inf1, 'V', "Lid does not require change by the SubnSet !", "setPortInfoHca");
1316
if ((pReqPortInfo->master_sm_base_lid == 0) || (cl_ntoh16(pReqPortInfo->master_sm_base_lid) >= 0xbfff))
1318
MSGREG(err5, 'E', "PortInfo Invalid master SM Lid set for $ !", "setPortInfoHca");
1319
MSGSND(err5, pReqPortInfo->master_sm_base_lid);
1320
status = IB_MAD_STATUS_INVALID_FIELD;
1325
else pNodePortInfo->master_sm_base_lid = pReqPortInfo->master_sm_base_lid;
1329
uint8_t mKeyProtectBits;
1331
reqLmc = ib_port_info_get_lmc(pReqPortInfo);
1332
ib_port_info_set_lmc(pNodePortInfo, reqLmc);
1333
mKeyProtectBits = ib_port_info_get_mpb(pReqPortInfo);
1334
ib_port_info_set_mpb(pNodePortInfo, mKeyProtectBits);
1342
nMtuReq = ib_port_info_get_neighbor_mtu(pReqPortInfo);
1343
mtuCap = ib_port_info_get_mtu_cap(pNodePortInfo);
1344
if ((nMtuReq == 0) || (nMtuReq > 5) || (nMtuReq > mtuCap))
1346
MSGREG(err4, 'E', "PortInfo N - MTU set for $ with MTU Cap $ !", "setPortInfoHca");
1347
MSGSND(err4, nMtuReq, mtuCap);
1348
status = IB_MAD_STATUS_INVALID_FIELD;
1353
ib_port_info_set_neighbor_mtu(pNodePortInfo, nMtuReq);
1354
masterSmSl = ib_port_info_get_smsl(pReqPortInfo);
1355
ib_port_info_set_smsl(pNodePortInfo, masterSmSl);
1362
reqOpVl = ib_port_info_get_op_vls(pReqPortInfo);
1363
vlCap = ib_port_info_get_vl_cap(pNodePortInfo);
1365
if ((reqOpVl > vlCap) || (reqOpVl > 5))
1367
MSGREG(err5, 'E', "PortInfo Operational VL set for $ with VL Cap $ !", "setPortInfoHca");
1368
MSGSND(err5, reqOpVl, vlCap);
1369
status = IB_MAD_STATUS_INVALID_FIELD;
1374
if (reqOpVl) ib_port_info_set_op_vls(pNodePortInfo, reqOpVl);
1381
int IBMSSma::setPortInfo(ibms_mad_msg_t &respMadMsg,
1382
ibms_mad_msg_t &reqMadMsg,
1384
ib_port_info_t portInfoElm,
1388
ib_net16_t status = 0;
1390
status = setPortInfoGeneral(respMadMsg, reqMadMsg, inPort, portInfoElm, portNum);
1393
MSGREG(err0, 'E', "PortInfo failed in setPortInfoGeneral !", "setPortInfo");
1399
if (pSimNode->nodeInfo.node_type == IB_NODE_TYPE_SWITCH)
1401
//Handling a switch port
1402
//TODO add different handling for: Enhanced Port0
1403
//MSGREG(inf4, 'V', "PortInfo SubnSet of Switch Enhanced Port0 !", "setPortInfo");
1409
status = setPortInfoSwBasePort(respMadMsg, reqMadMsg, inPort, portInfoElm, portNum);
1412
{ // 3) External ports
1413
status = setPortInfoSwExtPort(respMadMsg, reqMadMsg, inPort, portInfoElm, portNum);
1417
{ //Handling an HCA port
1418
status = setPortInfoHca(respMadMsg, reqMadMsg, inPort, portInfoElm, portNum);
1422
MSGREG(err1, 'E', "PortInfo failed in Node specific area !", "setPortInfo");
1429
ib_port_info_t* pNodePortInfo;
1431
pRespMad = (ib_smp_t*) &respMadMsg.header;
1432
pNodePortInfo = &(pSimNode->nodePortsInfo[portNum]);
1433
memcpy (pRespMad->data, pNodePortInfo, sizeof(portInfoElm));
1440
int IBMSSma::portInfoMad(ibms_mad_msg_t &respMadMsg, ibms_mad_msg_t &reqMadMsg, uint8_t inPort)
1445
ib_net16_t status = 0;
1446
ib_port_info_t portInfoElm;
1448
portNum = cl_ntoh32(reqMadMsg.header.attr_mod);
1449
//non existing port of the device
1450
if (portNum > pSimNode->nodeInfo.num_ports)
1452
MSGREG(err0, 'E', "PortInfo request for non-existing port", "portInfoMad");
1454
status = IB_MAD_STATUS_INVALID_FIELD;
1460
//for HCAs if AM is 0 then handling the port that received the mad
1461
if ((pSimNode->nodeInfo.node_type == IB_NODE_TYPE_CA) && (portNum == 0))
1466
portInfoElm = pSimNode->nodePortsInfo[portNum];
1467
if (reqMadMsg.header.method == IB_MAD_METHOD_GET)
1469
MSGREG(inf2, 'V', "PortInfo SubnGet !", "portInfoMad");
1473
pRespMad = (ib_smp_t*) &respMadMsg.header;
1475
portInfoElm.local_port_num = inPort;
1476
memcpy (pRespMad->data, &(portInfoElm), sizeof(portInfoElm));
1481
status = setPortInfo(respMadMsg, reqMadMsg, inPort, portInfoElm, portNum);
1488
int IBMSSma::pKeyMad(ibms_mad_msg_t &respMadMsg, ibms_mad_msg_t &reqMadMsg, uint8_t inPort)
1494
ib_net16_t status = 0;
1495
ib_pkey_table_t PKeyBlockElem;
1496
ib_pkey_table_t* pPkeyBlockElem;
1500
if (pSimNode->nodeInfo.node_type == IB_NODE_TYPE_CA)
1504
if (portNum == 0) portNum = 1;
1507
else if (pSimNode->nodeInfo.node_type == IB_NODE_TYPE_SWITCH)
1509
portNum = cl_ntoh32(reqMadMsg.header.attr_mod) >> 16;
1511
PKeyBlockNum = cl_ntoh32(reqMadMsg.header.attr_mod) & 0xffff;
1512
MSGREG(inf2, 'V', "Partition Key block number $ on port $ !", "pKeyMad");
1513
MSGSND(inf2, PKeyBlockNum, portNum);
1515
if (PKeyBlockNum > (cl_ntoh16(pSimNode->nodeInfo.partition_cap) / 32))
1517
MSGREG(err0, 'E', "Partition Key block number $ is un-supported limited to $ blocks !", "pKeyMad");
1518
MSGSND(err0, PKeyBlockNum, (cl_ntoh16(pSimNode->nodeInfo.partition_cap) / 32));
1519
status = IB_MAD_STATUS_INVALID_FIELD;
1524
//TODO add P_Key size check for external ports of a switch (in SwitchInfo structure)
1526
pRespMad = (ib_smp_t*) &respMadMsg.header;
1527
pReqMad = (ib_smp_t*) &reqMadMsg.header;
1528
if (reqMadMsg.header.method == IB_MAD_METHOD_GET)
1530
MSGREG(inf3, 'V', "Partition Key SubnGet !", "pKeyMad");
1533
PKeyBlockElem = (pSimNode->nodePortPKeyTable[portNum])[PKeyBlockNum];
1534
memcpy ((void*)(pRespMad->data), (void*)(&PKeyBlockElem), sizeof(ib_pkey_table_t));
1538
MSGREG(inf4, 'V', "Partition Key SubnSet !", "pKeyMad");
1541
pPkeyBlockElem = &(pSimNode->nodePortPKeyTable[portNum])[PKeyBlockNum];
1542
memcpy ((void*)(pPkeyBlockElem), (void*)(pReqMad->data), sizeof(ib_pkey_table_t));
1543
memcpy ((void*)(pRespMad->data), (void*)(pReqMad->data), sizeof(ib_pkey_table_t));
1550
int IBMSSma::madValidation(ibms_mad_msg_t &madMsg)
1554
ib_net16_t status = 0;
1556
// we handle Get or Set or trap repress
1557
if ((madMsg.header.method != IB_MAD_METHOD_GET) &&
1558
(madMsg.header.method != IB_MAD_METHOD_SET) &&
1559
(madMsg.header.method != IB_MAD_METHOD_TRAP_REPRESS))
1561
MSGREG(wrn0, 'W', "We are not handling getResp Method.", "madValidation");
1563
status = IB_MAD_STATUS_INVALID_FIELD;
1569
ibms_dump_mad( madMsg, RCV);
1575
int IBMSSma::processMad(uint8_t inPort, ibms_mad_msg_t &madMsg)
1580
ibms_mad_msg_t respMadMsg;
1581
ib_net16_t status = 0;
1582
uint16_t attributeId = 0;
1584
//1. Verify rcv MAD validity.
1585
status = madValidation(madMsg);
1588
//TODO need to do it more cleanly
1593
if (madMsg.header.method == IB_MAD_METHOD_TRAP_REPRESS)
1595
MSGREG(inf0, 'I', "--- Received Trap Repress ---", "processMad");
1602
//2. Switch according to the attribute to the mad handle
1603
// and call appropriate function
1604
MSGREG(inf1, 'I', "Process Mad got the following attribute: $ !", "processMad");
1605
MSGSND(inf1, cl_ntoh16(madMsg.header.attr_id));
1606
attributeId = madMsg.header.attr_id;
1608
// copy header from request to the response
1610
ib_smp_t* pRespSmp = (ib_smp_t*)(&respMadMsg.header);
1611
ib_smp_t* pReqSmp = (ib_smp_t*)(&madMsg.header);
1612
memcpy(pRespSmp, pReqSmp, sizeof(ib_smp_t));
1615
// perform m_key check
1616
unsigned mPort = inPort;
1617
if (pSimNode->nodeInfo.node_type == IB_NODE_TYPE_SWITCH)
1620
ib_net64_t m_key1 = ((ib_smp_t*)(&madMsg.header))->m_key;
1622
pthread_mutex_lock(&vPT[mPort].mut);
1623
ib_net64_t m_key2 = vPT[mPort].pInfo->m_key;
1625
MSGREG(inf21, 'I', "Mkeys current: $, received: $!", "processMad");
1626
MSGSND(inf21, cl_ntoh64(m_key2), cl_ntoh64(m_key1));
1628
if (m_key2 && (m_key1 != m_key2) && madMsg.header.method == IB_MAD_METHOD_SET) {
1629
MSGREG(inf22, 'I', "Mkeys mismatch!", "processMad");
1632
// Timer already running
1633
if (vPT[mPort].timerOn) {
1634
MSGREG(inf2, 'I', "Timer already on, counter: $!", "processMad");
1635
MSGSND(inf2,vPT[mPort].counter);
1638
pthread_mutex_unlock(&vPT[mPort].mut);
1643
vPT[mPort].counter = cl_ntoh16(vPT[mPort].pInfo->m_key_lease_period);
1644
vPT[mPort].timerOn = 1;
1647
tmp.data = &vPT[mPort];
1649
MSGREG(inf2, 'I', "Starting timer with counter $!", "processMad");
1650
MSGSND(inf2,vPT[mPort].counter);
1652
pthread_mutex_unlock(&vPT[mPort].mut);
1662
if ((m_key1 == m_key2) && (vPT[mPort].timerOn)) {
1663
MSGREG(inf2, 'I', "Stopping timer!", "processMad");
1666
vPT[mPort].timerOn = 0;
1667
pthread_mutex_unlock(&vPT[mPort].mut);
1668
mkeyTimer.unreg(&vPT[mPort]);
1671
pthread_mutex_unlock(&vPT[mPort].mut);
1673
switch (attributeId) {
1674
case IB_MAD_ATTR_NODE_DESC:
1675
MSGREG(inf5, 'I', "Attribute being handled is $ !", "processMad");
1676
MSGSND(inf5, CL_NTOH16(IB_MAD_ATTR_NODE_DESC));
1677
if (madMsg.header.method != IB_MAD_METHOD_GET)
1679
MSGREG(err6, 'E', "NodeDescription was sent with Method other then Get !", "sma");
1683
return IB_MAD_STATUS_UNSUP_METHOD_ATTR;
1686
status = nodeDescMad(respMadMsg);
1688
case IB_MAD_ATTR_NODE_INFO:
1689
MSGREG(inf4, 'I', "Attribute being handled is $ !", "processMad");
1690
MSGSND(inf4, CL_NTOH16(IB_MAD_ATTR_NODE_INFO));
1691
if (madMsg.header.method != IB_MAD_METHOD_GET)
1693
MSGREG(err2, 'E', "NodeInfo was sent with Method other then Get !", "sma");
1697
return IB_MAD_STATUS_UNSUP_METHOD_ATTR;
1700
status = nodeInfoMad(respMadMsg, inPort);
1702
case IB_MAD_ATTR_PORT_INFO:
1703
MSGREG(inf6, 'I', "Attribute being handled is $ !", "processMad");
1704
MSGSND(inf6, CL_NTOH16(IB_MAD_ATTR_PORT_INFO));
1706
status = portInfoMad(respMadMsg, madMsg, inPort);
1708
case IB_MAD_ATTR_P_KEY_TABLE:
1709
MSGREG(inf7, 'I', "Attribute being handled is $ !", "processMad");
1710
MSGSND(inf7, CL_NTOH16(IB_MAD_ATTR_P_KEY_TABLE));
1712
status = pKeyMad(respMadMsg, madMsg, inPort);
1714
case IB_MAD_ATTR_SWITCH_INFO:
1715
MSGREG(inf8, 'I', "Attribute being handled is $ !", "processMad");
1716
MSGSND(inf8, CL_NTOH16(IB_MAD_ATTR_SWITCH_INFO));
1718
status = switchInfoMad(respMadMsg, madMsg);
1720
case IB_MAD_ATTR_LIN_FWD_TBL:
1721
MSGREG(inf9, 'I', "Attribute being handled is $ !", "processMad");
1722
MSGSND(inf9, CL_NTOH16(IB_MAD_ATTR_LIN_FWD_TBL));
1724
status = lftMad(respMadMsg, madMsg);
1726
case IB_MAD_ATTR_MCAST_FWD_TBL:
1727
MSGREG(inf10, 'I', "Attribute being handled is $ !", "processMad");
1728
MSGSND(inf10, CL_NTOH16(IB_MAD_ATTR_MCAST_FWD_TBL));
1730
status = mftMad(respMadMsg, madMsg);
1732
case IB_MAD_ATTR_SLVL_TABLE:
1733
MSGREG(inf11, 'I', "Attribute being handled is $ !", "processMad");
1734
MSGSND(inf11, CL_NTOH16(IB_MAD_ATTR_SLVL_TABLE));
1736
status = sl2VlMad(respMadMsg, madMsg, inPort);
1738
case IB_MAD_ATTR_VL_ARBITRATION:
1739
MSGREG(inf12, 'I', "Attribute being handled is $ !", "processMad");
1740
MSGSND(inf12, CL_NTOH16(IB_MAD_ATTR_VL_ARBITRATION));
1742
status = vlArbMad(respMadMsg, madMsg, inPort);
1745
MSGREG(err1, 'E', "No handler for requested attribute:$", "processMad");
1746
MSGSND(err1, cl_ntoh16(attributeId));
1747
status = IB_MAD_STATUS_UNSUP_METHOD_ATTR;
1749
//TODO need to do it more cleanly
1755
//ib_mad_init_response( respMadMsg, respMadMsg, status);
1757
ib_smp_t* pRespSmp = (ib_smp_t*)(&respMadMsg.header);
1758
ib_smp_t* pReqSmp = (ib_smp_t*)(&madMsg.header);
1760
respMadMsg.addr = madMsg.addr;
1761
respMadMsg.addr.slid = madMsg.addr.dlid;
1762
respMadMsg.addr.dlid = madMsg.addr.slid;
1763
if (respMadMsg.header.method == IB_MAD_METHOD_SET)
1765
respMadMsg.header.method = IB_MAD_METHOD_GET_RESP;
1767
else respMadMsg.header.method |= IB_MAD_METHOD_RESP_MASK;
1768
//only if direct then set D-bit
1769
if (respMadMsg.header.mgmt_class == 0x81)
1771
respMadMsg.header.status = status | IB_SMP_DIRECTION;
1773
pRespSmp->dr_slid = pReqSmp->dr_dlid;
1774
pRespSmp->dr_dlid = pReqSmp->dr_slid;
1778
ibms_dump_mad( respMadMsg, SND);
1779
pSimNode->getSim()->getDispatcher()->dispatchMad(pSimNode, inPort,