VOL-2227:Fix for Max PON Ports

Change-Id: I093c3a4cf1726cf7f94cf8833d1e8a4e775c762b
diff --git a/adaptercore/device_handler_test.go b/adaptercore/device_handler_test.go
index 588796c..26b86ba 100644
--- a/adaptercore/device_handler_test.go
+++ b/adaptercore/device_handler_test.go
@@ -189,7 +189,19 @@
 	dh.eventMgr = &OpenOltEventMgr{eventProxy: &mocks.MockEventProxy{}}
 	dh.transitionMap = &TransitionMap{}
 	dh.portStats = &OpenOltStatisticsMgr{}
-	dh.metrics = &pmmetrics.PmMetrics{}
+
+	var pmNames = []string{
+		"rx_bytes",
+		"rx_packets",
+		"rx_mcast_packets",
+		"rx_bcast_packets",
+		"tx_bytes",
+		"tx_packets",
+		"tx_mcast_packets",
+		"tx_bcast_packets",
+	}
+
+	dh.metrics = pmmetrics.NewPmMetrics(device.Id, pmmetrics.Frequency(2), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
 	return dh
 }
 
@@ -1071,7 +1083,7 @@
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			go func() {
-				time.Sleep(2 * time.Minute)
+				time.Sleep(66 * time.Second) // startCollector inside waits for 1 min, so we stop it after 6 secs of running
 				tt.args.dh.stopCollector <- true
 			}()
 			startCollector(tt.args.dh)
diff --git a/adaptercore/olt_platform.go b/adaptercore/olt_platform.go
index 6f0d58c..0186712 100644
--- a/adaptercore/olt_platform.go
+++ b/adaptercore/olt_platform.go
@@ -19,6 +19,7 @@
 
 import (
 	"errors"
+
 	"github.com/opencord/voltha-lib-go/v2/pkg/flows"
 	"github.com/opencord/voltha-lib-go/v2/pkg/log"
 	ofp "github.com/opencord/voltha-protos/v2/go/openflow_13"
@@ -27,6 +28,10 @@
 
 /*=====================================================================
 
+@TODO: Looks like this Flow id concept below is not used anywhere
+       Propose to remove the below documentation of Flow Id on confirmation
+       of the same
+
 Flow id
 
     Identifies a flow within a single OLT
@@ -51,19 +56,19 @@
 
     OpenFlow port number corresponding to PON UNI
 
-     15       11              4      0
+     20        12              4      0
     +--+--------+--------------+------+
-    |0 | pon id |    onu id    |   0  |
+    |0 | pon id |    onu id    |uni id|
     +--+--------+--------------+------+
 
-    pon id = 4 bits = 16 PON ports
-    onu id = 7 bits = 128 ONUs per PON port
+    pon id = 8 bits = 256 PON ports
+    onu id = 8 bits = 256 ONUs per PON port
 
 Logical (OF) NNI port number
 
-    OpenFlow port number corresponding to PON UNI
+    OpenFlow port number corresponding to PON NNI
 
-     16                             0
+     20                             0
     +--+----------------------------+
     |1 |                    intf_id |
     +--+----------------------------+
@@ -75,14 +80,34 @@
 
     OpenFlow port number corresponding to PON OLT ports
 
-     31    28                                 0
+     31     28                                 0
     +--------+------------------------~~~------+
     |  0x2   |          pon intf id            |
     +--------+------------------------~~~------+
 */
 
-//MaxOnusPerPon value
-var MaxOnusPerPon = 128
+const (
+	// Number of bits for the physical UNI of the ONUs
+	bitsForUniID = 4
+	// Number of bits for the ONU ID
+	bitsForONUID = 8
+	// Number of bits for PON ID
+	bitsForPONID = 8
+	// Number of bits to differentiate between UNI and NNI Logical Port
+	bitsForUNINNIDiff = 1
+	//MaxOnusPerPon is Max number of ONUs on any PON port
+	MaxOnusPerPon = (1 << bitsForONUID)
+	//MaxPonsPerOlt is Max number of PON ports on any OLT
+	MaxPonsPerOlt = (1 << bitsForPONID)
+	//MaxUnisPerOnu is the Max number of UNI ports on any ONU
+	MaxUnisPerOnu = (1 << bitsForUniID)
+	//Bit position where the differentiation bit is located
+	nniUniDiffPos = (bitsForUniID + bitsForONUID + bitsForPONID)
+	//Bit position where the marker for PON port type of OF port is present
+	ponIntfMarkerPos = 28
+	//Value of marker used to distinguish PON port type of OF port
+	ponIntfMarkerValue = 0x2
+)
 
 //MinUpstreamPortID value
 var MinUpstreamPortID = 0xfffd
@@ -98,31 +123,31 @@
 	if limit > MaxOnusPerPon {
 		log.Warn("Warning: exceeded the MAX ONUS per PON")
 	}
-	return (intfID << 11) | (onuID << 4) | uniID
+	return (intfID << (bitsForUniID + bitsForONUID)) | (onuID << bitsForUniID) | uniID
 }
 
 //OnuIDFromPortNum returns ONUID derived from portNumber
 func OnuIDFromPortNum(portNum uint32) uint32 {
-	return (portNum >> 4) & 127
+	return (portNum >> bitsForUniID) & (MaxOnusPerPon - 1)
 }
 
 //IntfIDFromUniPortNum returns IntfID derived from portNum
 func IntfIDFromUniPortNum(portNum uint32) uint32 {
-	return (portNum >> 11) & 15
+	return (portNum >> (bitsForUniID + bitsForONUID)) & (MaxPonsPerOlt - 1)
 }
 
 //UniIDFromPortNum return UniID derived from portNum
 func UniIDFromPortNum(portNum uint32) uint32 {
-	return (portNum) & 0xF
+	return (portNum) & (MaxUnisPerOnu - 1)
 }
 
 //IntfIDToPortNo returns portId derived from intftype, intfId and portType
 func IntfIDToPortNo(intfID uint32, intfType voltha.Port_PortType) uint32 {
 	if (intfType) == voltha.Port_ETHERNET_NNI {
-		return (1 << 16) | intfID
+		return (1 << nniUniDiffPos) | intfID
 	}
 	if (intfType) == voltha.Port_PON_OLT {
-		return (2 << 28) | intfID
+		return (ponIntfMarkerValue << ponIntfMarkerPos) | intfID
 	}
 	return 0
 }
@@ -130,10 +155,10 @@
 //PortNoToIntfID returns portnumber derived from interfaceID
 func PortNoToIntfID(portno uint32, intfType voltha.Port_PortType) uint32 {
 	if (intfType) == voltha.Port_ETHERNET_NNI {
-		return (1 << 16) ^ portno
+		return (1 << nniUniDiffPos) ^ portno
 	}
 	if (intfType) == voltha.Port_PON_OLT {
-		return (2 << 28) ^ portno
+		return (ponIntfMarkerValue << ponIntfMarkerPos) ^ portno
 	}
 	return 0
 }
@@ -145,10 +170,10 @@
 
 //IntfIDToPortTypeName returns port type derived from the intfId
 func IntfIDToPortTypeName(intfID uint32) voltha.Port_PortType {
-	if ((2 << 28) ^ intfID) < 16 {
+	if ((ponIntfMarkerValue << ponIntfMarkerPos) ^ intfID) < MaxPonsPerOlt {
 		return voltha.Port_PON_OLT
 	}
-	if (intfID & (1 << 16)) == (1 << 16) {
+	if (intfID & (1 << nniUniDiffPos)) == (1 << nniUniDiffPos) {
 		return voltha.Port_ETHERNET_NNI
 	}
 	return voltha.Port_ETHERNET_UNI
@@ -169,7 +194,7 @@
 			return true
 		}
 	}
-	return (outPort & (1 << 16)) == (1 << 16)
+	return (outPort & (1 << nniUniDiffPos)) == (1 << nniUniDiffPos)
 }
 
 //IsControllerBoundFlow returns true/false
@@ -184,7 +209,7 @@
 
 //OnuIDFromUniPortNum returns onuId from give portNum information.
 func OnuIDFromUniPortNum(portNum uint32) uint32 {
-	return (portNum >> 4) & 0x7F
+	return (portNum >> bitsForUniID) & (MaxOnusPerPon - 1)
 }
 
 //FlowExtractInfo fetches uniport from the flow, based on which it gets and returns ponInf, onuID, uniID, inPort and ethType
diff --git a/adaptercore/olt_platform_test.go b/adaptercore/olt_platform_test.go
index c842d02..7a799b8 100644
--- a/adaptercore/olt_platform_test.go
+++ b/adaptercore/olt_platform_test.go
@@ -39,10 +39,10 @@
 		want uint32
 	}{
 		// TODO: Add test cases.
-		{"MkUniPortNum-1", args{1, 1, 1}, ((1 * 2048) + (1 * 16) + 1)},
-		{"MkUniPortNum-2", args{4, 5, 6}, ((4 * 2048) + (5 * 16) + 6)},
+		{"MkUniPortNum-1", args{1, 1, 1}, ((1 * 4096) + (1 * 16) + 1)},
+		{"MkUniPortNum-2", args{4, 5, 6}, ((4 * 4096) + (5 * 16) + 6)},
 		// Negative test cases to cover the log.warn
-		{"MkUniPortNum-3", args{4, 130, 6}, ((4 * 2048) + (130 * 16) + 6)},
+		{"MkUniPortNum-3", args{4, 130, 6}, ((4 * 4096) + (130 * 16) + 6)},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -65,8 +65,8 @@
 		want uint32
 	}{
 		// TODO: Add test cases.
-		{"OnuIDFromPortNum-1", args{portNum: 8096}, ((8096 / 16) & 127)},
-		{"OnuIDFromPortNum-2", args{portNum: 9095}, ((9095 / 16) & 127)},
+		{"OnuIDFromPortNum-1", args{portNum: 8096}, ((8096 / 16) & 255)},
+		{"OnuIDFromPortNum-2", args{portNum: 9095}, ((9095 / 16) & 255)},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -89,9 +89,9 @@
 		want uint32
 	}{
 		// TODO: Add test cases.
-		{"IntfIDFromUniPortNum-1", args{portNum: 8096}, ((8096 / 2048) & 15)},
+		{"IntfIDFromUniPortNum-1", args{portNum: 8096}, ((8096 / 4096) & 15)},
 		// Negative Testcase
-		{"IntfIDFromUniPortNum-2", args{portNum: 1024}, ((1024 / 2048) & 15)},
+		{"IntfIDFromUniPortNum-2", args{portNum: 1024}, ((1024 / 4096) & 15)},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -140,7 +140,7 @@
 		want uint32
 	}{
 		// TODO: Add test cases.
-		{"IntfIDToPortNo-1", args{intfID: 120, intfType: voltha.Port_ETHERNET_NNI}, (uint32(math.Pow(2, 16)) + 120)},
+		{"IntfIDToPortNo-1", args{intfID: 120, intfType: voltha.Port_ETHERNET_NNI}, (uint32(math.Pow(2, 20)) + 120)},
 		{"IntfIDToPortNo-2", args{intfID: 1024, intfType: voltha.Port_ETHERNET_UNI}, 0},
 		{"IntfIDToPortNo-3", args{intfID: 456, intfType: voltha.Port_PON_OLT}, (uint32(2*math.Pow(2, 28)) + 456)},
 		{"IntfIDToPortNo-4", args{intfID: 28, intfType: voltha.Port_PON_ONU}, 0},
@@ -198,7 +198,7 @@
 		want voltha.Port_PortType
 	}{
 		// TODO: Add test cases.
-		{"IntfIDToPortTypeName-1", args{intfID: 65536}, voltha.Port_ETHERNET_NNI},
+		{"IntfIDToPortTypeName-1", args{intfID: 1048576}, voltha.Port_ETHERNET_NNI},
 		{"IntfIDToPortTypeName-2", args{intfID: 1000}, voltha.Port_ETHERNET_UNI},
 		{"IntfIDToPortTypeName-2", args{intfID: input}, voltha.Port_PON_OLT},
 	}
@@ -225,8 +225,8 @@
 		uniID  uint32
 	}{
 		// TODO: Add test cases.
-		{"ExtractAccessFromFlow-1", args{inPort: 100, outPort: 65536}, 100, 0, 6, 4},
-		{"ExtractAccessFromFlow-1", args{inPort: 65536, outPort: 10}, 10, 0, 0, 10},
+		{"ExtractAccessFromFlow-1", args{inPort: 100, outPort: 1048576}, 100, 0, 6, 4},
+		{"ExtractAccessFromFlow-2", args{inPort: 1048576, outPort: 10}, 10, 0, 0, 10},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -259,10 +259,9 @@
 	}{
 		// TODO: Add test cases.
 		{"TestIsUpstream-1", args{outPort: 65533}, true},
-		{"TestIsUpstream-2", args{outPort: 65536}, true},
-		{"TestIsUpstream-3", args{outPort: 65537}, true},
-		{"TestIsUpstream-4", args{outPort: 65538}, true},
-		{"TestIsUpstream-5", args{outPort: 65539}, true},
+		{"TestIsUpstream-2", args{outPort: 1048576}, true},
+		{"TestIsUpstream-3", args{outPort: 1048577}, true},
+		{"TestIsUpstream-4", args{outPort: 1048578}, true},
 		{"TestIsUpstream-6", args{outPort: 1000}, false},
 	}
 	for _, tt := range tests {
diff --git a/adaptercore/openolt_flowmgr.go b/adaptercore/openolt_flowmgr.go
index 8ee2a11..e3f0ccb 100644
--- a/adaptercore/openolt_flowmgr.go
+++ b/adaptercore/openolt_flowmgr.go
@@ -135,8 +135,6 @@
 	VlanPCPMask = 0xFF
 	//VlanvIDMask constant
 	VlanvIDMask = 0xFFF
-	//MaxPonPorts constant
-	MaxPonPorts = 16
 	//IntfID constant
 	IntfID = "intfId"
 	//OnuID constant
@@ -168,7 +166,7 @@
 
 //OpenOltFlowMgr creates the Structure of OpenOltFlowMgr obj
 type OpenOltFlowMgr struct {
-	techprofile        []tp.TechProfileIf
+	techprofile        map[uint32]tp.TechProfileIf
 	deviceHandler      *DeviceHandler
 	resourceMgr        *rsrcMgr.OpenOltResourceMgr
 	onuIdsLock         sync.RWMutex
@@ -187,7 +185,7 @@
 
 	flowMgr.deviceHandler = dh
 	flowMgr.resourceMgr = rMgr
-	flowMgr.techprofile = make([]tp.TechProfileIf, MaxPonPorts)
+	flowMgr.techprofile = make(map[uint32]tp.TechProfileIf)
 	if err = flowMgr.populateTechProfilePerPonPort(); err != nil {
 		log.Error("Error while populating tech profile mgr\n")
 		return nil
diff --git a/adaptercore/openolt_flowmgr_test.go b/adaptercore/openolt_flowmgr_test.go
index e6de810..3b19081 100644
--- a/adaptercore/openolt_flowmgr_test.go
+++ b/adaptercore/openolt_flowmgr_test.go
@@ -83,7 +83,7 @@
 	packetInGemPort[rsrcMgr.PacketInInfoKey{IntfID: 2, OnuID: 2, LogicalPort: 2}] = 2
 
 	flwMgr.packetInGemPort = packetInGemPort
-	tps := make([]tp.TechProfileIf, len(rMgr.ResourceMgrs))
+	tps := make(map[uint32]tp.TechProfileIf)
 	for key := range rMgr.ResourceMgrs {
 		tps[key] = mocks.MockTechProfile{TpID: key}
 	}
@@ -526,10 +526,10 @@
 	}{
 		// TODO: Add test cases.
 		{"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 1, false},
-		{"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "nni", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 65537, false},
+		{"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "nni", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 1048577, false},
 		// Negative Test cases.
 		{"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 2, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 0, true},
-		{"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 0, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 2064, false},
+		{"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 0, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 4112, false},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {