blob: a52d653668692cb78c802fea297bec928d65b668 [file] [log] [blame]
William Kurkian6f436d02019-02-06 16:25:01 -05001#
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
William Kurkian8b1690c2019-03-04 16:53:22 -050017from voltha_protos.device_pb2 import Port
18import voltha_protos.device_pb2 as dev_pb2
William Kurkian6f436d02019-02-06 16:25:01 -050019
20"""
21Encoding of identifiers
22=======================
23
24Flow 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
56Logical (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
67
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
79class OpenOltPlatform(object):
80 MAX_PONS_PER_OLT = 16
81 MAX_ONUS_PER_PON = 32
82 MAX_UNIS_PER_ONU = 16
83
84 def __init__(self, log, resource_mgr):
85 self.log = log
86 self.resource_mgr = resource_mgr
87
88 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
94
95 #def mk_flow_id(self, intf_id, onu_id, idx):
96 # return intf_id << 9 | onu_id << 4 | idx
97
98 def uni_id_from_port_num(self, port_num):
99 return port_num & 0xF
100
101 def onu_id_from_port_num(self, port_num):
102 return (port_num >> 4) & 0x7F
103
104
105 def intf_id_from_uni_port_num(self, port_num):
106 return (port_num >> 11) & 0xF
107
108
109 def intf_id_from_pon_port_no(self, port_no):
110 return port_no & 0xF
111
112
113 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')
120
121
122 def intf_id_from_nni_port_num(self, port_num):
123 return port_num & 0xFFFF
124
125
126 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:
132 return Port.ETHERNET_UNI
133
134 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)
139
140 def extract_access_from_flow(self, in_port, out_port):
141 if self.is_upstream(out_port):
142 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))
146 else:
147 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))
151
152 def is_upstream(self, out_port):
153
154 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
160
161 return False
162 #
163 #def max_onus_per_pon(self):
164 # return OpenOltPlatform.MAX_ONUS_PER_PON