blob: a44eafcebc68096616b0aab527cf5632b9514b64 [file] [log] [blame]
Shad Ansari22920932018-05-17 00:33:34 +00001#
2# Copyright 2018 the original author or authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17from voltha.protos.device_pb2 import Port
mzadige4ad1d22018-07-27 15:27:22 -040018import voltha.protos.device_pb2 as dev_pb2
Shad Ansari22920932018-05-17 00:33:34 +000019
20"""
21Encoding of identifiers
22=======================
23
Shad Ansari22920932018-05-17 00:33:34 +000024Flow id
25
26 Identifies a flow within a single OLT
27 Flow Id is unique per OLT
28 Multiple GEM ports can map to same flow id
29
30 13 11 4 0
31 +--------+--------------+------+
32 | pon id | onu id | Flow |
33 | | | idx |
34 +--------+--------------+------+
35
36 14 bits = 16384 flows (per OLT).
37
38 pon id = 4 bits = 16 PON ports
39 onu id = 7 bits = 128 ONUss per PON port
40 Flow index = 3 bits = 4 bi-directional flows per ONU
41 = 8 uni-directional flows per ONU
42
43
44Logical (OF) UNI port number
45
46 OpenFlow port number corresponding to PON UNI
47
48 15 11 4 0
49 +--+--------+--------------+------+
50 |0 | pon id | onu id | 0 |
51 +--+--------+--------------+------+
52
53 pon id = 4 bits = 16 PON ports
54 onu id = 7 bits = 128 ONUs per PON port
55
Nicolas Palpacuer5780e152018-09-05 17:25:42 -040056Logical (OF) NNI port number
57
58 OpenFlow port number corresponding to PON UNI
59
60 16 0
61 +--+----------------------------+
62 |1 | intf_id |
63 +--+----------------------------+
64
65 No overlap with UNI port number space
66
Shad Ansari22920932018-05-17 00:33:34 +000067
68PON OLT (OF) port number
69
70 OpenFlow port number corresponding to PON OLT ports
71
72 31 28 0
73 +--------+------------------------~~~------+
74 | 0x2 | pon intf id |
75 +--------+------------------------~~~------+
76
77"""
78
Shad Ansaricd20a6d2018-10-02 14:36:33 +000079class OpenOltPlatform(object):
Craig Lutgenabd9c842018-11-15 23:58:27 +000080 MAX_PONS_PER_OLT = 16
81 MAX_ONUS_PER_PON = 32
82 MAX_UNIS_PER_ONU = 16
Shad Ansaricd20a6d2018-10-02 14:36:33 +000083
Craig Lutgenabd9c842018-11-15 23:58:27 +000084 def __init__(self, log, resource_mgr):
Shad Ansaricd20a6d2018-10-02 14:36:33 +000085 self.log = log
Craig Lutgenabd9c842018-11-15 23:58:27 +000086 self.resource_mgr = resource_mgr
Shad Ansaricd20a6d2018-10-02 14:36:33 +000087
Craig Lutgenabd9c842018-11-15 23:58:27 +000088 def mk_uni_port_num(self, intf_id, onu_id, uni_id):
89 assert intf_id < OpenOltPlatform.MAX_PONS_PER_OLT
90 assert onu_id < OpenOltPlatform.MAX_ONUS_PER_PON
91 assert uni_id < OpenOltPlatform.MAX_UNIS_PER_ONU
92 self.resource_mgr.assert_uni_id_limit(intf_id, onu_id, uni_id)
93 return intf_id << 11 | onu_id << 4 | uni_id
Shad Ansari22920932018-05-17 00:33:34 +000094
Craig Lutgenabd9c842018-11-15 23:58:27 +000095 #def mk_flow_id(self, intf_id, onu_id, idx):
96 # return intf_id << 9 | onu_id << 4 | idx
Shad Ansarif9d2d102018-06-13 02:15:26 +000097
Craig Lutgenabd9c842018-11-15 23:58:27 +000098 def uni_id_from_port_num(self, port_num):
99 return port_num & 0xF
Shad Ansari22920932018-05-17 00:33:34 +0000100
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000101 def onu_id_from_port_num(self, port_num):
102 return (port_num >> 4) & 0x7F
Shad Ansari22920932018-05-17 00:33:34 +0000103
Shad Ansarif9d2d102018-06-13 02:15:26 +0000104
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000105 def intf_id_from_uni_port_num(self, port_num):
106 return (port_num >> 11) & 0xF
Shad Ansari22920932018-05-17 00:33:34 +0000107
Shad Ansarif9d2d102018-06-13 02:15:26 +0000108
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000109 def intf_id_from_pon_port_no(self, port_no):
110 return port_no & 0xF
Nicolas Palpacuer36a93442018-05-23 17:38:57 -0400111
Shad Ansarif9d2d102018-06-13 02:15:26 +0000112
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000113 def intf_id_to_port_no(self, intf_id, intf_type):
114 if intf_type is Port.ETHERNET_NNI:
115 return (0x1 << 16) | intf_id
116 elif intf_type is Port.PON_OLT:
117 return 0x2 << 28 | intf_id
118 else:
119 raise Exception('Invalid port type')
Nicolas Palpacuer7d902812018-06-07 16:17:09 -0400120
Shad Ansarif9d2d102018-06-13 02:15:26 +0000121
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000122 def intf_id_from_nni_port_num(self, port_num):
123 return port_num & 0xFFFF
mzadige4ad1d22018-07-27 15:27:22 -0400124
mzadige4ad1d22018-07-27 15:27:22 -0400125
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000126 def intf_id_to_port_type_name(self, intf_id):
127 if (2 << 28 ^ intf_id) < 16:
128 return Port.PON_OLT
129 elif intf_id & (0x1 << 16) == (0x1 << 16):
130 return Port.ETHERNET_NNI
131 else:
Craig Lutgenabd9c842018-11-15 23:58:27 +0000132 return Port.ETHERNET_UNI
mzadige4ad1d22018-07-27 15:27:22 -0400133
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000134 def port_type_name_by_port_index(self, port_index):
135 try:
136 return dev_pb2._PORT_PORTTYPE.values_by_number[port_index].name
137 except Exception as err:
138 raise Exception(err)
mzadige4ad1d22018-07-27 15:27:22 -0400139
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000140 def extract_access_from_flow(self, in_port, out_port):
141 if self.is_upstream(out_port):
Craig Lutgenabd9c842018-11-15 23:58:27 +0000142 return (in_port,
143 self.intf_id_from_uni_port_num(in_port),
144 self.onu_id_from_port_num(in_port),
145 self.uni_id_from_port_num(in_port))
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000146 else:
Craig Lutgenabd9c842018-11-15 23:58:27 +0000147 return (out_port,
148 self.intf_id_from_uni_port_num(out_port),
149 self.onu_id_from_port_num(out_port),
150 self.uni_id_from_port_num(out_port))
Nicolas Palpacuer0c7c3162018-08-08 11:27:57 -0400151
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000152 def is_upstream(self, out_port):
Nicolas Palpacuer5780e152018-09-05 17:25:42 -0400153
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000154 if out_port in [0xfffd, 0xfffffffd]:
155 # To Controller
156 return True
157 if (out_port & (0x1 << 16)) == (0x1 << 16):
158 # NNI interface
159 return True
Nicolas Palpacuer0c7c3162018-08-08 11:27:57 -0400160
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000161 return False
Craig Lutgenabd9c842018-11-15 23:58:27 +0000162 #
163 #def max_onus_per_pon(self):
164 # return OpenOltPlatform.MAX_ONUS_PER_PON