@@ -45,9 +45,7 @@
#define MAXLINEARCAP (30*1024)
#define MAXMCASTCAP 1024
#define LASTBLOCK32 (MAXMCASTCAP/32-1)
-// NUMBEROFPORTMASK means that 32port switches could only be build
-#define NUMBEROFPORTMASK 2
-#define LASTPORTMASK (NUMBEROFPORTMASK-1)
+#define MCASTMASKSIZE 16
// linkwidth == 4X - must be one width only 1,2 or 8
#define LINKWIDTH_1x 1
#define LINKWIDTH_4x 2
@@ -229,6 +227,7 @@ struct Switch {
int linearFDBtop;
int portchange;
int lifetime;
+ int numportmask;
uint8_t switchinfo[64];
Node *node;
uint8_t *fdb;
@@ -513,18 +513,19 @@ static int do_multicastforwtbl(Port * port, unsigned op, uint32_t mod,
int blockposition;
Switch *sw = port->node->sw;
+ int lastportmask = sw->numportmask + 1;
if (!sw) // not a Switch?
return ERR_ATTR_UNSUPPORTED;
VERB("requested : Block32 %d PortMask %d", numBlock32, numPortMsk);
- if (numBlock32 > LASTBLOCK32 || numPortMsk > LASTPORTMASK) {
+ if (numBlock32 > LASTBLOCK32 || numPortMsk > lastportmask) {
int8_t zeroblock[64] = { 0 };
mad_set_array(data, 0, IB_MULTICAST_FORW_TBL_F, zeroblock);
return 0;
}
- blockposition = (numBlock32 * NUMBEROFPORTMASK + numPortMsk) * 64;
+ blockposition = (numBlock32 * sw->numportmask + numPortMsk) * 64;
if (op == IB_MAD_METHOD_SET)
mad_get_array(data, 0, IB_MULTICAST_FORW_TBL_F,
sw->mfdb + blockposition);
@@ -245,6 +245,7 @@ static Switch *new_switch(Node * nd, int set_esp0)
sw->node = nd;
sw->linearcap = maxlinearcap; // assume identical val for all switches
sw->multicastcap = maxmcastcap; // assume identical val for all switches
+ sw->numportmask = (nd->numports + MCASTMASKSIZE) / MCASTMASKSIZE;
memcpy(sw->switchinfo, switchinfo, sizeof(sw->switchinfo));
mad_set_field(sw->switchinfo, 0, IB_SW_LINEAR_FDB_CAP_F, sw->linearcap);
mad_set_field(sw->switchinfo, 0, IB_SW_MCAST_FDB_CAP_F,
@@ -253,13 +254,13 @@ static Switch *new_switch(Node * nd, int set_esp0)
mad_set_field(sw->switchinfo, 0, IB_SW_ENHANCED_PORT0_F,
set_esp0 > 0);
sw->fdb = malloc(maxlinearcap*sizeof(sw->fdb[0]));
- sw->mfdb = malloc(maxmcastcap*NUMBEROFPORTMASK*sizeof(uint16_t));
+ sw->mfdb = malloc(maxmcastcap * sw->numportmask * sizeof(uint16_t));
if (!sw->fdb || !sw->mfdb) {
IBPANIC("new_switch: no mem: %m");
return NULL;
}
memset(sw->fdb, 0xff, maxlinearcap*sizeof(sw->fdb[0]));
- memset(sw->mfdb, 0, maxmcastcap*NUMBEROFPORTMASK*sizeof(uint16_t));
+ memset(sw->mfdb, 0, maxmcastcap * sw->numportmask * sizeof(uint16_t));
return sw;
}