blob: 8de776f2fed8de08ba8d390a4a66653aa893f78d [file] [log] [blame]
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001/*
Girish Gowdraa707e7c2019-11-07 11:36:13 +05302 * Copyright 2018-present Open Networking Foundation
Shad Ansarib7b0ced2018-05-11 21:53:32 +00003
Girish Gowdraa707e7c2019-11-07 11:36:13 +05304 * 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
Shad Ansarib7b0ced2018-05-11 21:53:32 +00007
Girish Gowdraa707e7c2019-11-07 11:36:13 +05308 * http://www.apache.org/licenses/LICENSE-2.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00009
Girish Gowdraa707e7c2019-11-07 11:36:13 +053010 * 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 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +000016
17#include <iostream>
18#include <memory>
19#include <string>
20
21#include "Queue.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000022#include <sstream>
Nicolas Palpacuer9c352082018-08-14 16:37:14 -040023#include <chrono>
24#include <thread>
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080025#include <bitset>
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000026#include <inttypes.h>
Jason Huangbf45ffb2019-10-30 17:29:02 +080027#include <unistd.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000028
Craig Lutgen88a22ad2018-10-04 12:30:46 -050029#include "device.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000030#include "core.h"
31#include "indications.h"
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040032#include "stats_collection.h"
Nicolas Palpacuer73222e02018-07-16 12:20:26 -040033#include "error_format.h"
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040034#include "state.h"
Craig Lutgen88a22ad2018-10-04 12:30:46 -050035#include "utils.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000036
37extern "C"
38{
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000039#include <bcmolt_api.h>
40#include <bcmolt_host_api.h>
41#include <bcmolt_api_model_supporting_enums.h>
42
43#include <bal_version.h>
44#include <bcmolt_api_conn_mgr.h>
45//CLI header files
46#include <bcmcli_session.h>
47#include <bcmcli.h>
48#include <bcm_api_cli.h>
49
50#include <bcmos_common.h>
51#include <bcm_config.h>
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -040052// FIXME : dependency problem
53// #include <bcm_common_gpon.h>
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040054// #include <bcm_dev_log_task.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000055}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000056
Shad Ansarib7b0ced2018-05-11 21:53:32 +000057
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040058dev_log_id openolt_log_id = bcm_dev_log_id_register("OPENOLT", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
59dev_log_id omci_log_id = bcm_dev_log_id_register("OMCI", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
60
Craig Lutgen88a22ad2018-10-04 12:30:46 -050061#define BAL_RSC_MANAGER_BASE_TM_SCHED_ID 16384
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080062#define MAX_TM_QUEUE_ID 8192
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000063#define MAX_TM_QMP_ID 16
64#define TMQ_MAP_PROFILE_SIZE 8
65#define MAX_TM_SCHED_ID 1023
66#define MAX_SUBS_TM_SCHED_ID (MAX_SUPPORTED_PON == 16 ? MAX_TM_SCHED_ID-4-16 : MAX_TM_SCHED_ID-10-64)
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080067#define EAP_ETHER_TYPE 34958
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000068#define XGS_BANDWIDTH_GRANULARITY 16000
69#define GPON_BANDWIDTH_GRANULARITY 32000
70#define FILL_ARRAY(ARRAY,START,END,VALUE) for(int i=START;i<END;ARRAY[i++]=VALUE);
71#define COUNT_OF(array) (sizeof(array) / sizeof(array[0]))
72
73#define GET_FLOW_INTERFACE_TYPE(type) \
74 (type == BCMOLT_FLOW_INTERFACE_TYPE_PON) ? "PON" : \
75 (type == BCMOLT_FLOW_INTERFACE_TYPE_NNI) ? "NNI" : \
76 (type == BCMOLT_FLOW_INTERFACE_TYPE_HOST) ? "HOST" : "unknown"
77#define GET_PKT_TAG_TYPE(type) \
78 (type == BCMOLT_PKT_TAG_TYPE_UNTAGGED) ? "UNTAG" : \
79 (type == BCMOLT_PKT_TAG_TYPE_SINGLE_TAG) ? "SINGLE_TAG" : \
80 (type == BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG) ? "DOUBLE_TAG" : "unknown"
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040081
Craig Lutgen88a22ad2018-10-04 12:30:46 -050082static unsigned int num_of_nni_ports = 0;
83static unsigned int num_of_pon_ports = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000084static std::string intf_technologies[MAX_SUPPORTED_PON];
Craig Lutgen88a22ad2018-10-04 12:30:46 -050085static const std::string UNKNOWN_TECH("unknown");
Craig Lutgenb2601f02018-10-23 13:04:31 -050086static const std::string MIXED_TECH("mixed");
87static std::string board_technology(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000088static std::string chip_family(UNKNOWN_TECH);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -080089static unsigned int OPENOLT_FIELD_LEN = 200;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000090static std::string firmware_version = "Openolt.2019.07.01";
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040091
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000092const uint32_t tm_upstream_sched_id_start = (MAX_SUPPORTED_PON == 16 ? \
93 MAX_TM_SCHED_ID-3 : MAX_TM_SCHED_ID-9);
94const uint32_t tm_downstream_sched_id_start = (MAX_SUPPORTED_PON == 16 ? \
95 tm_upstream_sched_id_start-16 : tm_upstream_sched_id_start-64);
96
97/* Max Queue ID supported is 7 so based on priority_q configured for GEMPORTS
98in TECH PROFILE respective Queue ID from this list will be used for both
99US and DS Queues*/
100const uint32_t queue_id_list[8] = {0, 1, 2, 3, 4, 5, 6, 7};
101
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700102const std::string upstream = "upstream";
103const std::string downstream = "downstream";
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000104bcmolt_oltid dev_id = 0;
105
106/* Current session */
107static bcmcli_session *current_session;
108static bcmcli_entry *api_parent_dir;
109bcmos_bool status_bcm_cli_quit = BCMOS_FALSE;
110bcmos_task bal_cli_thread;
111const char *bal_cli_thread_name = "bal_cli_thread";
112uint16_t flow_id_counters = 0;
113int flow_id_data[16384][2];
Shad Ansariedef2132018-08-10 22:14:50 +0000114State state;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400115
Craig Lutgen967a1d02018-11-27 10:41:51 -0600116static std::map<uint32_t, uint32_t> flowid_to_port; // For mapping upstream flows to logical ports
117static std::map<uint32_t, uint32_t> flowid_to_gemport; // For mapping downstream flows into gemports
118static std::map<uint32_t, std::set<uint32_t> > port_to_flows; // For mapping logical ports to downstream flows
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800119
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000120/* This represents the Key to 'sched_map' map.
121 Represents (pon_intf_id, onu_id, uni_id, direction) */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800122typedef std::tuple<uint32_t, uint32_t, uint32_t, std::string> sched_map_key_tuple;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000123/* 'sched_map' maps sched_map_key_tuple to DBA (Upstream) or
124 Subscriber (Downstream) Scheduler ID */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800125static std::map<sched_map_key_tuple, int> sched_map;
126
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -0500127/* This represents the Key to 'qos_type_map' map.
128 Represents (pon_intf_id, onu_id, uni_id) */
129typedef std::tuple<uint32_t, uint32_t, uint32_t> qos_type_map_key_tuple;
130/* 'qos_type_map' maps qos_type_map_key_tuple to qos_type*/
131static std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type> qos_type_map;
132
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000133/* This represents the Key to 'sched_qmp_id_map' map.
134Represents (sched_id, pon_intf_id, onu_id, uni_id) */
135typedef std::tuple<uint32_t, uint32_t, uint32_t, uint32_t> sched_qmp_id_map_key_tuple;
136/* 'sched_qmp_id_map' maps sched_qmp_id_map_key_tuple to TM Queue Mapping Profile ID */
137static std::map<sched_qmp_id_map_key_tuple, int> sched_qmp_id_map;
138/* 'qmp_id_to_qmp_map' maps TM Queue Mapping Profile ID to TM Queue Mapping Profile */
139static std::map<int, std::vector < uint32_t > > qmp_id_to_qmp_map;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800140
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800141std::bitset<MAX_TM_SCHED_ID> tm_sched_bitset;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000142std::bitset<MAX_TM_QMP_ID> tm_qmp_bitset;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800143
144static bcmos_fastlock data_lock;
Craig Lutgen967a1d02018-11-27 10:41:51 -0600145
146#define MIN_ALLOC_ID_GPON 256
147#define MIN_ALLOC_ID_XGSPON 1024
148
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800149static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
150 uint32_t port_no, uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, \
151 uint32_t priority, tech_profile::SchedulingPolicy sched_policy,
152 tech_profile::TrafficShapingInfo traffic_shaping_info);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000153static bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800154static bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -0500155 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
156static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
157 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000158static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
159static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
160
161uint16_t get_dev_id(void) {
162 return dev_id;
163}
Shad Ansari627b5782018-08-13 22:49:32 +0000164
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400165// Stubbed defntions of bcmolt_cfg_get required for unit-test
166#ifdef TEST_MODE
167extern bcmos_errno bcmolt_cfg_get__bal_state_stub(bcmolt_oltid olt_id, void* ptr);
168extern bcmos_errno bcmolt_cfg_get__olt_topology_stub(bcmolt_oltid olt_id, void* ptr);
169#endif
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800170/**
171* Returns the default NNI (Upstream direction) or PON (Downstream direction) scheduler
172* Every NNI port and PON port have default scheduler.
173* The NNI0 default scheduler ID is 18432, and NNI1 is 18433 and so on.
174* Similarly, PON0 default scheduler ID is 16384. PON1 is 16385 and so on.
175*
176* @param intf_id NNI or PON interface ID
177* @param direction "upstream" or "downstream"
178*
179* @return default scheduler ID for the given interface.
180*/
181static inline int get_default_tm_sched_id(int intf_id, std::string direction) {
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700182 if (direction.compare(upstream) == 0) {
183 return tm_upstream_sched_id_start + intf_id;
184 } else if (direction.compare(downstream) == 0) {
185 return tm_downstream_sched_id_start + intf_id;
186 }
187 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000188 OPENOLT_LOG(ERROR, openolt_log_id, "invalid direction - %s\n", direction.c_str());
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700189 return 0;
190 }
191}
192
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800193/**
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800194* Gets a unique tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
195* The tm_sched_id is locally cached in a map, so that it can rendered when necessary.
196* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
197*
198* @param intf_id NNI or PON intf ID
199* @param onu_id ONU ID
200* @param uni_id UNI ID
201* @param gemport_id GEM Port ID
202* @param direction Upstream or downstream
203*
204* @return tm_sched_id
205*/
206uint32_t get_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
207 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
208 int sched_id = -1;
209
210 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
211 if (it != sched_map.end()) {
212 sched_id = it->second;
213 }
214 if (sched_id != -1) {
215 return sched_id;
216 }
217
218 bcmos_fastlock_lock(&data_lock);
219 // Complexity of O(n). Is there better way that can avoid linear search?
220 for (sched_id = 0; sched_id < MAX_TM_SCHED_ID; sched_id++) {
221 if (tm_sched_bitset[sched_id] == 0) {
222 tm_sched_bitset[sched_id] = 1;
223 break;
224 }
225 }
226 bcmos_fastlock_unlock(&data_lock, 0);
227
228 if (sched_id < MAX_TM_SCHED_ID) {
229 bcmos_fastlock_lock(&data_lock);
230 sched_map[key] = sched_id;
231 bcmos_fastlock_unlock(&data_lock, 0);
232 return sched_id;
233 } else {
234 return -1;
235 }
236}
237
238/**
239* Free tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
240*
241* @param intf_id NNI or PON intf ID
242* @param onu_id ONU ID
243* @param uni_id UNI ID
244* @param gemport_id GEM Port ID
245* @param direction Upstream or downstream
246*/
247void free_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
248 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
249 std::map<sched_map_key_tuple, int>::const_iterator it;
250 bcmos_fastlock_lock(&data_lock);
251 it = sched_map.find(key);
252 if (it != sched_map.end()) {
253 tm_sched_bitset[it->second] = 0;
254 sched_map.erase(it);
255 }
256 bcmos_fastlock_unlock(&data_lock, 0);
257}
258
259bool is_tm_sched_id_present(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
260 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000261 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
262 if (it != sched_map.end()) {
263 return true;
264 }
265 return false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800266}
267
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000268/**
269* Check whether given two tm qmp profiles are equal or not
270*
271* @param tmq_map_profileA <vector> TM QUEUE MAPPING PROFILE
272* @param tmq_map_profileB <vector> TM QUEUE MAPPING PROFILE
273*
274* @return boolean, true if given tmq_map_profiles are equal else false
275*/
276
277bool check_tm_qmp_equality(std::vector<uint32_t> tmq_map_profileA, std::vector<uint32_t> tmq_map_profileB) {
278 for (uint32_t i = 0; i < TMQ_MAP_PROFILE_SIZE; i++) {
279 if (tmq_map_profileA[i] != tmq_map_profileB[i]) {
280 return false;
281 }
282 }
283 return true;
Shad Ansari627b5782018-08-13 22:49:32 +0000284}
285
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000286/**
287* Modifies given queues_pbit_map to parsable format
288* e.g: Modifes "0b00000101" to "10100000"
289*
290* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
291* @param size Queue count
292*
293* @return string queues_pbit_map
294*/
295std::string* get_valid_queues_pbit_map(std::string *queues_pbit_map, uint32_t size) {
296 for(uint32_t i=0; i < size; i++) {
297 /* Deletes 2 characters from index number 0 */
298 queues_pbit_map[i].erase(0, 2);
299 std::reverse(queues_pbit_map[i].begin(), queues_pbit_map[i].end());
300 }
301 return queues_pbit_map;
302}
303
304/**
305* Creates TM QUEUE MAPPING PROFILE for given queues_pbit_map and queues_priority_q
306*
307* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
308* @param queues_priority_q PRIORITY_Q configured for each GEM in TECH PROFILE
309* @param size Queue count
310*
311* @return <vector> TM QUEUE MAPPING PROFILE
312*/
313std::vector<uint32_t> get_tmq_map_profile(std::string *queues_pbit_map, uint32_t *queues_priority_q, uint32_t size) {
314 std::vector<uint32_t> tmq_map_profile(8,0);
315
316 for(uint32_t i=0; i < size; i++) {
317 for (uint32_t j = 0; j < queues_pbit_map[i].size(); j++) {
318 if (queues_pbit_map[i][j]=='1') {
319 tmq_map_profile.at(j) = queue_id_list[queues_priority_q[i]];
320 }
321 }
322 }
323 return tmq_map_profile;
324}
325
326/**
327* Gets corresponding tm_qmp_id for a given tmq_map_profile
328*
329* @param <vector> TM QUEUE MAPPING PROFILE
330*
331* @return tm_qmp_id
332*/
333int get_tm_qmp_id(std::vector<uint32_t> tmq_map_profile) {
334 int tm_qmp_id = -1;
335
336 std::map<int, std::vector < uint32_t > >::const_iterator it = qmp_id_to_qmp_map.begin();
337 while(it != qmp_id_to_qmp_map.end()) {
338 if(check_tm_qmp_equality(tmq_map_profile, it->second)) {
339 tm_qmp_id = it->first;
340 break;
341 }
342 it++;
343 }
344 return tm_qmp_id;
345}
346
347/**
348* Updates sched_qmp_id_map with given sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id
349*
350* @param upstream/downstream sched_id
351* @param PON intf ID
352* @param onu_id ONU ID
353* @param uni_id UNI ID
354* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
355*/
356void update_sched_qmp_id_map(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
357 uint32_t uni_id, int tm_qmp_id) {
358 bcmos_fastlock_lock(&data_lock);
359 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
360 sched_qmp_id_map.insert(make_pair(key, tm_qmp_id));
361 bcmos_fastlock_unlock(&data_lock, 0);
362}
363
364/**
365* Gets corresponding tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
366*
367* @param upstream/downstream sched_id
368* @param PON intf ID
369* @param onu_id ONU ID
370* @param uni_id UNI ID
371*
372* @return tm_qmp_id
373*/
374int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
375 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
376 int tm_qmp_id = -1;
377
378 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
379 if (it != sched_qmp_id_map.end()) {
380 tm_qmp_id = it->second;
381 }
382 return tm_qmp_id;
383}
384
385/**
386* Gets a unique tm_qmp_id for a given tmq_map_profile
387* The tm_qmp_id is locally cached in a map, so that it can be rendered when necessary.
388* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
389*
390* @param upstream/downstream sched_id
391* @param PON intf ID
392* @param onu_id ONU ID
393* @param uni_id UNI ID
394* @param <vector> TM QUEUE MAPPING PROFILE
395*
396* @return tm_qmp_id
397*/
398int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, \
399 std::vector<uint32_t> tmq_map_profile) {
400 int tm_qmp_id;
401
402 bcmos_fastlock_lock(&data_lock);
403 /* Complexity of O(n). Is there better way that can avoid linear search? */
404 for (tm_qmp_id = 0; tm_qmp_id < MAX_TM_QMP_ID; tm_qmp_id++) {
405 if (tm_qmp_bitset[tm_qmp_id] == 0) {
406 tm_qmp_bitset[tm_qmp_id] = 1;
407 break;
408 }
409 }
410 bcmos_fastlock_unlock(&data_lock, 0);
411
412 if (tm_qmp_id < MAX_TM_QMP_ID) {
413 bcmos_fastlock_lock(&data_lock);
414 qmp_id_to_qmp_map.insert(make_pair(tm_qmp_id, tmq_map_profile));
415 bcmos_fastlock_unlock(&data_lock, 0);
416 update_sched_qmp_id_map(sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id);
417 return tm_qmp_id;
418 } else {
419 return -1;
420 }
421}
422
423/**
424* Free tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
425*
426* @param upstream/downstream sched_id
427* @param PON intf ID
428* @param onu_id ONU ID
429* @param uni_id UNI ID
430* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
431*
432* @return boolean, true if no more reference for TM QMP else false
433*/
434bool free_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
435 uint32_t uni_id, int tm_qmp_id) {
436 bool result;
437 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
438 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
439 bcmos_fastlock_lock(&data_lock);
440 if (it != sched_qmp_id_map.end()) {
441 sched_qmp_id_map.erase(it);
442 }
443 bcmos_fastlock_unlock(&data_lock, 0);
444
445 uint32_t tm_qmp_ref_count = 0;
446 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it2 = sched_qmp_id_map.begin();
447 while(it2 != sched_qmp_id_map.end()) {
448 if(it2->second == tm_qmp_id) {
449 tm_qmp_ref_count++;
450 }
451 it2++;
452 }
453
454 if (tm_qmp_ref_count == 0) {
455 std::map<int, std::vector < uint32_t > >::const_iterator it3 = qmp_id_to_qmp_map.find(tm_qmp_id);
456 if (it3 != qmp_id_to_qmp_map.end()) {
457 bcmos_fastlock_lock(&data_lock);
458 tm_qmp_bitset[tm_qmp_id] = 0;
459 qmp_id_to_qmp_map.erase(it3);
460 bcmos_fastlock_unlock(&data_lock, 0);
461 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So clearing it\n", \
462 tm_qmp_id, tm_qmp_ref_count);
463 result = true;
464 }
465 } else {
466 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So not clearing it\n", \
467 tm_qmp_id, tm_qmp_ref_count);
468 result = false;
469 }
470 return result;
471}
472
473/**
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -0500474* Returns qos type as string
475*
476* @param qos_type bcmolt_egress_qos_type enum
477*/
478std::string get_qos_type_as_string(bcmolt_egress_qos_type qos_type) {
479 switch (qos_type)
480 {
481 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE: return "FIXED_QUEUE";
482 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE: return "TC_TO_QUEUE";
483 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC: return "PBIT_TO_TC";
484 case BCMOLT_EGRESS_QOS_TYPE_NONE: return "NONE";
485 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE: return "PRIORITY_TO_QUEUE";
486 default: OPENOLT_LOG(ERROR, openolt_log_id, "qos-type-not-supported %d\n", qos_type);
487 return "qos-type-not-supported";
488 }
489}
490
491/**
492* Gets/Updates qos type for given pon_intf_id, onu_id, uni_id
493*
494* @param PON intf ID
495* @param onu_id ONU ID
496* @param uni_id UNI ID
497* @param queue_size TrafficQueues Size
498*
499* @return qos_type
500*/
501bcmolt_egress_qos_type get_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t queue_size = 0) {
502 qos_type_map_key_tuple key(pon_intf_id, onu_id, uni_id);
503 bcmolt_egress_qos_type egress_qos_type = BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
504 std::string qos_string;
505
506 std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type>::const_iterator it = qos_type_map.find(key);
507 if (it != qos_type_map.end()) {
508 egress_qos_type = it->second;
509 qos_string = get_qos_type_as_string(egress_qos_type);
510 OPENOLT_LOG(INFO, openolt_log_id, "Qos-type for subscriber connected to pon_intf_id %d, onu_id %d and uni_id %d is %s\n", \
511 pon_intf_id, onu_id, uni_id, qos_string.c_str());
512 }
513 else {
514 /* QOS Type has been pre-defined as Fixed Queue but it will be updated based on number of GEMPORTS
515 associated for a given subscriber. If GEM count = 1 for a given subscriber, qos_type will be Fixed Queue
516 else Priority to Queue */
517 egress_qos_type = (queue_size > 1) ? \
518 BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE : BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
519 bcmos_fastlock_lock(&data_lock);
520 qos_type_map.insert(make_pair(key, egress_qos_type));
521 bcmos_fastlock_unlock(&data_lock, 0);
522 qos_string = get_qos_type_as_string(egress_qos_type);
523 OPENOLT_LOG(INFO, openolt_log_id, "Qos-type for subscriber connected to pon_intf_id %d, onu_id %d and uni_id %d is %s\n", \
524 pon_intf_id, onu_id, uni_id, qos_string.c_str());
525 }
526 return egress_qos_type;
527}
528
529/**
530* Clears qos type for given pon_intf_id, onu_id, uni_id
531*
532* @param PON intf ID
533* @param onu_id ONU ID
534* @param uni_id UNI ID
535*/
536void clear_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
537 qos_type_map_key_tuple key(pon_intf_id, onu_id, uni_id);
538 std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type>::const_iterator it = qos_type_map.find(key);
539 bcmos_fastlock_lock(&data_lock);
540 if (it != qos_type_map.end()) {
541 qos_type_map.erase(it);
542 OPENOLT_LOG(INFO, openolt_log_id, "Cleared Qos-type for subscriber connected to pon_intf_id %d, onu_id %d and uni_id %d\n", \
543 pon_intf_id, onu_id, uni_id);
544 }
545 bcmos_fastlock_unlock(&data_lock, 0);
546}
547
548/**
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000549* Returns Scheduler/Queue direction as string
550*
551* @param direction as specified in tech_profile.proto
552*/
553std::string GetDirection(int direction) {
554 switch (direction)
555 {
556 case tech_profile::Direction::UPSTREAM: return upstream;
557 case tech_profile::Direction::DOWNSTREAM: return downstream;
558 default: OPENOLT_LOG(ERROR, openolt_log_id, "direction-not-supported %d\n", direction);
559 return "direction-not-supported";
560 }
561}
562
563inline const char *get_flow_acton_command(uint32_t command) {
564 char actions[200] = { };
565 char *s_actions_ptr = actions;
566 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
567 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
568 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
569 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
570 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
571 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
572 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
573 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
574 return s_actions_ptr;
575}
576
577char* openolt_read_sysinfo(const char* field_name, char* field_val)
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800578{
579 FILE *fp;
580 /* Prepare the command*/
581 char command[150];
582
583 snprintf(command, sizeof command, "bash -l -c \"onlpdump -s\" | perl -ne 'print $1 if /%s: (\\S+)/'", field_name);
584 /* Open the command for reading. */
585 fp = popen(command, "r");
586 if (fp == NULL) {
587 /*The client has to check for a Null field value in this case*/
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000588 OPENOLT_LOG(INFO, openolt_log_id, "Failed to query the %s\n", field_name);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800589 return field_val;
590 }
591
592 /*Read the field value*/
593 if (fp) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000594 uint8_t ret;
595 ret = fread(field_val, OPENOLT_FIELD_LEN, 1, fp);
596 if (ret >= OPENOLT_FIELD_LEN)
597 OPENOLT_LOG(INFO, openolt_log_id, "Read data length %u\n", ret);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800598 pclose(fp);
599 }
600 return field_val;
601}
602
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400603Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500604 device_info->set_vendor(VENDOR_ID);
605 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400606 device_info->set_hardware_version("");
607 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500608 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500609 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500610
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800611 char serial_number[OPENOLT_FIELD_LEN];
612 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
613 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000614 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800615 device_info->set_device_serial_number(serial_number);
616
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700617 char device_id[OPENOLT_FIELD_LEN];
618 memset(device_id, '\0', OPENOLT_FIELD_LEN);
619 openolt_read_sysinfo("MAC", device_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000620 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700621 device_info->set_device_id(device_id);
622
Craig Lutgenb2601f02018-10-23 13:04:31 -0500623 // Legacy, device-wide ranges. To be deprecated when adapter
624 // is upgraded to support per-interface ranges
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000625 if (board_technology == "XGS-PON") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500626 device_info->set_onu_id_start(1);
627 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600628 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500629 device_info->set_alloc_id_end(16383);
630 device_info->set_gemport_id_start(1024);
631 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500632 device_info->set_flow_id_start(1);
633 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500634 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000635 else if (board_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500636 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500637 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600638 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500639 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500640 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500641 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500642 device_info->set_flow_id_start(1);
643 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500644 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500645
646 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
647 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
648 std::string intf_technology = intf_technologies[intf_id];
649 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
650 if(range == nullptr) {
651 range = device_info->add_ranges();
652 ranges[intf_technology] = range;
653 range->set_technology(intf_technology);
654
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000655 if (intf_technology == "XGS-PON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500656 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
657
658 pool = range->add_pools();
659 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
660 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
661 pool->set_start(1);
662 pool->set_end(255);
663
664 pool = range->add_pools();
665 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
666 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
667 pool->set_start(1024);
668 pool->set_end(16383);
669
670 pool = range->add_pools();
671 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
672 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
673 pool->set_start(1024);
674 pool->set_end(65535);
675
676 pool = range->add_pools();
677 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
678 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
679 pool->set_start(1);
680 pool->set_end(16383);
681 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000682 else if (intf_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500683 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
684
685 pool = range->add_pools();
686 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
687 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
688 pool->set_start(1);
689 pool->set_end(127);
690
691 pool = range->add_pools();
692 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
693 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
694 pool->set_start(256);
695 pool->set_end(757);
696
697 pool = range->add_pools();
698 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
699 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
700 pool->set_start(256);
701 pool->set_end(4095);
702
703 pool = range->add_pools();
704 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
705 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
706 pool->set_start(1);
707 pool->set_end(16383);
708 }
709 }
710
711 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500712 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400713
714 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500715 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400716 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
717 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500718 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400719 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500720 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
721 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400722
723 return Status::OK;
724}
725
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000726Status pushOltOperInd(uint32_t intf_id, const char *type, const char *state)
727{
728 openolt::Indication ind;
729 openolt::IntfOperIndication* intf_oper_ind = new openolt::IntfOperIndication;
730
731 intf_oper_ind->set_type(type);
732 intf_oper_ind->set_intf_id(intf_id);
733 intf_oper_ind->set_oper_state(state);
734 ind.set_allocated_intf_oper_ind(intf_oper_ind);
735 oltIndQ.push(ind);
736 return Status::OK;
737}
738
739#define CLI_HOST_PROMPT_FORMAT "BCM.%u> "
740
741/* Build CLI prompt */
742static void openolt_cli_get_prompt_cb(bcmcli_session *session, char *buf, uint32_t max_len)
743{
744 snprintf(buf, max_len, CLI_HOST_PROMPT_FORMAT, dev_id);
745}
746
747static int _bal_apiend_cli_thread_handler(long data)
748{
749 char init_string[]="\n";
750 bcmcli_session *sess = current_session;
751 bcmos_task_parm bal_cli_task_p_dummy;
752
753 /* Switch to interactive mode if not stopped in the init script */
754 if (!bcmcli_is_stopped(sess))
755 {
756 /* Force a CLI command prompt
757 * The string passed into the parse function
758 * must be modifiable, so a string constant like
759 * bcmcli_parse(current_session, "\n") will not
760 * work.
761 */
762 bcmcli_parse(sess, init_string);
763
764 /* Process user input until EOF or quit command */
765 bcmcli_driver(sess);
766 };
767 OPENOLT_LOG(INFO, openolt_log_id, "BAL API End CLI terminated\n");
768
769 /* Cleanup */
770 bcmcli_session_close(current_session);
771 bcmcli_token_destroy(NULL);
772 return 0;
773}
774
775/* Init API CLI commands for the current device */
776bcmos_errno bcm_openolt_api_cli_init(bcmcli_entry *parent_dir, bcmcli_session *session)
777{
778 bcmos_errno rc;
779
780 api_parent_dir = parent_dir;
781
782 rc = bcm_api_cli_set_commands(session);
783
784#ifdef BCM_SUBSYSTEM_HOST
785 /* Subscribe for device change indication */
786 rc = rc ? rc : bcmolt_olt_sel_ind_register(_api_cli_olt_change_ind);
787#endif
788
789 return rc;
790}
791
792static bcmos_errno bcm_cli_quit(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
793{
794 bcmcli_stop(session);
795 bcmcli_session_print(session, "CLI terminated by 'Quit' command\n");
796 status_bcm_cli_quit = BCMOS_TRUE;
797
798 return BCM_ERR_OK;
799}
800
801int get_status_bcm_cli_quit(void) {
802 return status_bcm_cli_quit;
803}
804
805bcmos_errno bcmolt_apiend_cli_init() {
806 bcmos_errno ret;
807 bcmos_task_parm bal_cli_task_p = {};
808 bcmos_task_parm bal_cli_task_p_dummy;
809
810 /** before creating the task, check if it is already created by the other half of BAL i.e. Core side */
811 if (BCM_ERR_OK != bcmos_task_query(&bal_cli_thread, &bal_cli_task_p_dummy))
812 {
813 /* Create BAL CLI thread */
814 bal_cli_task_p.name = bal_cli_thread_name;
815 bal_cli_task_p.handler = _bal_apiend_cli_thread_handler;
816 bal_cli_task_p.priority = TASK_PRIORITY_CLI;
817
818 ret = bcmos_task_create(&bal_cli_thread, &bal_cli_task_p);
819 if (BCM_ERR_OK != ret)
820 {
821 bcmos_printf("Couldn't create BAL API end CLI thread\n");
822 return ret;
823 }
824 }
825}
826
Shad Ansari627b5782018-08-13 22:49:32 +0000827Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000828 bcmos_errno err;
829 bcmolt_host_init_parms init_parms = {};
830 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
831 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000832
Shad Ansariedef2132018-08-10 22:14:50 +0000833 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000834
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500835 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000836 /* Initialize host subsystem */
837 err = bcmolt_host_init(&init_parms);
838 if (BCM_ERR_OK != err) {
839 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT\n");
840 return bcm_to_grpc_err(err, "Failed to init OLT");
841 }
842
843 bcmcli_session_parm mon_session_parm;
844 /* Create CLI session */
845 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
846 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
847 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
848 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
849 BUG_ON(rc != BCM_ERR_OK);
850
851 /* API CLI */
852 bcm_openolt_api_cli_init(NULL, current_session);
853
854 /* Add quit command */
855 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
856
857 err = bcmolt_apiend_cli_init();
858 if (BCM_ERR_OK != err) {
859 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init\n");
860 return bcm_to_grpc_err(err, "Failed to add apiend init");
861 }
862
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800863 bcmos_fastlock_init(&data_lock, 0);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000864 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600865
Jason Huangbf45ffb2019-10-30 17:29:02 +0800866 //check BCM daemon is connected or not
867 Status status = check_connection();
868 if (!status.ok())
869 return status;
870 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000871 Status status = SubscribeIndication();
872 if (!status.ok()) {
873 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
874 grpc_status_code_to_string(status.error_code()).c_str(),
875 status.error_message().c_str());
876 return status;
877 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800878
879 //check BAL state in initial stage
880 status = check_bal_ready();
881 if (!status.ok())
882 return status;
883 }
884
885 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000886 bcmos_errno err;
887 bcmolt_odid dev;
888 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
889 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400890 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000891 bcmolt_device_key dev_key = { };
892 dev_key.device_id = dev;
893 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
894 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
895 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800896 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000897 bcmolt_device_key key = {.device_id = dev};
898 bcmolt_device_connect oper;
899 BCMOLT_OPER_INIT(&oper, device, connect, key);
900 if (MODEL_ID == "asfvolt16") {
901 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
902 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
903 } else if (MODEL_ID == "asgvolt64") {
904 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
905 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
906 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
907 }
908 err = bcmolt_oper_submit(dev_id, &oper.hdr);
909 if (err) {
910 failed_enable_device_cnt ++;
911 OPENOLT_LOG(ERROR, openolt_log_id, "Enable PON device %d failed, err %d\n", dev, err);
912 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
913 OPENOLT_LOG(ERROR, openolt_log_id, "failed to enable all the pon ports\n");
914 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
915 }
916 }
917 bcmos_usleep(200000);
918 }
919 else {
920 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
921 state.activate();
922 }
923 }
924 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000925 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000926 }
Shad Ansariedef2132018-08-10 22:14:50 +0000927
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000928 /* Start CLI */
929 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400930 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000931 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400932}
933
934Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400935 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
936 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
937 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
938 //To overcome this disable is implemented by disabling all the PON ports
939 //associated with the device so as to support both in-band
940 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400941
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400942 Status status;
943 int failedCount = 0;
944 for (int i = 0; i < NumPonIf_(); i++) {
945 status = DisablePonIf_(i);
946 if (!status.ok()) {
947 failedCount+=1;
948 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
949 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400950 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400951 if (failedCount == 0) {
952 state.deactivate();
953 openolt::Indication ind;
954 openolt::OltIndication* olt_ind = new openolt::OltIndication;
955 olt_ind->set_oper_state("down");
956 ind.set_allocated_olt_ind(olt_ind);
957 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
958 oltIndQ.push(ind);
959 return Status::OK;
960 }
961 if (failedCount ==NumPonIf_()){
962 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
963 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400964
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400965 return grpc::Status(grpc::StatusCode::UNKNOWN, "failed to disable olt ,few PON ports are still in enabled state");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400966}
967
968Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400969 Status status;
970 int failedCount = 0;
971 for (int i = 0; i < NumPonIf_(); i++) {
972 status = EnablePonIf_(i);
973 if (!status.ok()) {
974 failedCount+=1;
975 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
976 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400977 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400978 if (failedCount == 0){
979 state.activate();
980 openolt::Indication ind;
981 openolt::OltIndication* olt_ind = new openolt::OltIndication;
982 olt_ind->set_oper_state("up");
983 ind.set_allocated_olt_ind(olt_ind);
984 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
985 oltIndQ.push(ind);
986 return Status::OK;
987 }
988 if (failedCount ==NumPonIf_()){
989 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
990 }
991 return grpc::Status(grpc::StatusCode::UNKNOWN, "failed to re-enable olt ,few PON ports are still in disabled state");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000992}
993
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000994bcmos_errno get_pon_interface_status(bcmolt_interface pon_ni, bcmolt_interface_state *state) {
995 bcmos_errno err;
996 bcmolt_pon_interface_key pon_key;
997 bcmolt_pon_interface_cfg pon_cfg;
998 pon_key.pon_ni = pon_ni;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000999
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001000 BCMOLT_CFG_INIT(&pon_cfg, pon_interface, pon_key);
1001 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, state);
1002 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, itu);
1003 err = bcmolt_cfg_get(dev_id, &pon_cfg.hdr);
1004 *state = pon_cfg.data.state;
1005 return err;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001006}
1007
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001008inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
1009 bcmos_errno err;
1010 bcmolt_flow_key flow_key;
1011 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001012
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001013 flow_key.flow_id = flow_id;
1014 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001015
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001016 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001017
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001018 switch (data_id) {
1019 case ONU_ID: //onu_id
1020 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
1021 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1022 if (err) {
1023 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id\n");
1024 return err;
1025 }
1026 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001027 case FLOW_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001028 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1029 if (err) {
1030 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type\n");
1031 return err;
1032 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001033 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001034 case SVC_PORT_ID: //svc_port_id
1035 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
1036 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1037 if (err) {
1038 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get svc_port_id\n");
1039 return err;
1040 }
1041 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001042 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001043 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
1044 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1045 if (err) {
1046 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority\n");
1047 return err;
1048 }
1049 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001050 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001051 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
1052 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1053 if (err) {
1054 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie\n");
1055 return err;
1056 }
1057 return flow_cfg.data.cookie;
1058 case INGRESS_INTF_TYPE: //ingress intf_type
1059 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
1060 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1061 if (err) {
1062 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_type\n");
1063 return err;
1064 }
1065 return flow_cfg.data.ingress_intf.intf_type;
1066 case EGRESS_INTF_TYPE: //egress intf_type
1067 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
1068 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1069 if (err) {
1070 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_type\n");
1071 return err;
1072 }
1073 return flow_cfg.data.egress_intf.intf_type;
1074 case INGRESS_INTF_ID: //ingress intf_id
1075 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
1076 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1077 if (err) {
1078 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_id\n");
1079 return err;
1080 }
1081 return flow_cfg.data.ingress_intf.intf_id;
1082 case EGRESS_INTF_ID: //egress intf_id
1083 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
1084 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1085 if (err) {
1086 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_id\n");
1087 return err;
1088 }
1089 return flow_cfg.data.egress_intf.intf_id;
1090 case CLASSIFIER_O_VID:
1091 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1092 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1093 if (err) {
1094 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_vid\n");
1095 return err;
1096 }
1097 return flow_cfg.data.classifier.o_vid;
1098 case CLASSIFIER_O_PBITS:
1099 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1100 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1101 if (err) {
1102 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_pbits\n");
1103 return err;
1104 }
1105 return flow_cfg.data.classifier.o_pbits;
1106 case CLASSIFIER_I_VID:
1107 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1108 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1109 if (err) {
1110 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_vid\n");
1111 return err;
1112 }
1113 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001114 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001115 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1116 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1117 if (err) {
1118 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_pbits\n");
1119 return err;
1120 }
1121 return flow_cfg.data.classifier.i_pbits;
1122 case CLASSIFIER_ETHER_TYPE:
1123 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1124 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1125 if (err) {
1126 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ether_type\n");
1127 return err;
1128 }
1129 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001130 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001131 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1132 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1133 if (err) {
1134 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ip_proto\n");
1135 return err;
1136 }
1137 return flow_cfg.data.classifier.ip_proto;
1138 case CLASSIFIER_SRC_PORT:
1139 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1140 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1141 if (err) {
1142 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier src_port\n");
1143 return err;
1144 }
1145 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001146 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001147 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1148 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1149 if (err) {
1150 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier dst_port\n");
1151 return err;
1152 }
1153 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001154 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001155 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1156 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1157 if (err) {
1158 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier pkt_tag_type\n");
1159 return err;
1160 }
1161 return flow_cfg.data.classifier.pkt_tag_type;
1162 case EGRESS_QOS_TYPE:
1163 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1164 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1165 if (err) {
1166 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos type\n");
1167 return err;
1168 }
1169 return flow_cfg.data.egress_qos.type;
1170 case EGRESS_QOS_QUEUE_ID:
1171 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1172 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1173 if (err) {
1174 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos queue_id\n");
1175 return err;
1176 }
1177 switch (flow_cfg.data.egress_qos.type) {
1178 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
1179 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
1180 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
1181 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
1182 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
1183 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
1184 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
1185 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
1186 case BCMOLT_EGRESS_QOS_TYPE_NONE:
1187 default:
1188 return -1;
1189 }
1190 case EGRESS_QOS_TM_SCHED_ID:
1191 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1192 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1193 if (err) {
1194 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos tm_sched_id\n");
1195 return err;
1196 }
1197 return flow_cfg.data.egress_qos.tm_sched.id;
1198 case ACTION_CMDS_BITMASK:
1199 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1200 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1201 if (err) {
1202 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action cmds_bitmask\n");
1203 return err;
1204 }
1205 return flow_cfg.data.action.cmds_bitmask;
1206 case ACTION_O_VID:
1207 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1208 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1209 if (err) {
1210 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_vid\n");
1211 return err;
1212 }
1213 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001214 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001215 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1216 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1217 if (err) {
1218 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_pbits\n");
1219 return err;
1220 }
1221 return flow_cfg.data.action.o_pbits;
1222 case ACTION_I_VID:
1223 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1224 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1225 if (err) {
1226 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_vid\n");
1227 return err;
1228 }
1229 return flow_cfg.data.action.i_vid;
1230 case ACTION_I_PBITS:
1231 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1232 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1233 if (err) {
1234 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_pbits\n");
1235 return err;
1236 }
1237 return flow_cfg.data.action.i_pbits;
1238 case STATE:
1239 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
1240 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1241 if (err) {
1242 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state\n");
1243 return err;
1244 }
1245 return flow_cfg.data.state;
1246 default:
1247 return BCM_ERR_INTERNAL;
1248 }
1249
1250 return err;
1251}
1252
1253Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001254 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001255 bcmolt_pon_interface_cfg interface_obj;
1256 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1257 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
1258 bcmolt_interface_state state;
1259
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001260 err = get_pon_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001261 if (err == BCM_ERR_OK) {
1262 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001263 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001264 return Status::OK;
1265 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001266 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001267 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1268 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1269 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
1270 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
1271 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
1272 BCMOLT_ONU_POST_DISCOVERY_MODE_ACTIVATE);
1273 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
1274 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
1275 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
1276 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
1277 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
1278 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
1279 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1280 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1281
1282 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1283 if (err != BCM_ERR_OK) {
1284 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable discovery onu, PON interface %d, err %d\n", intf_id, err);
1285 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
1286 }
1287 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1288 if (err != BCM_ERR_OK) {
1289 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", intf_id);
1290 return bcm_to_grpc_err(err, "Failed to enable PON interface");
1291 }
1292 else {
1293 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
1294 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
1295 CreateDefaultSched(intf_id, downstream);
1296 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001297 }
1298
1299 return Status::OK;
1300}
1301
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001302Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001303 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001304 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001305 bcmolt_device_key dev_key = { };
1306 bcmolt_olt_cfg olt_cfg = { };
1307 bcmolt_olt_key olt_key = { };
1308 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
1309 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001310
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001311 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
1312 topo.topology_maps.arr = &topo_map[0];
1313 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
1314 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
1315 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001316 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001317 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001318 #ifdef TEST_MODE
1319 // It is impossible to mock the setting of olt_cfg.data.bal_state because
1320 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
1321 // set the olt_cfg.data.topology. So a new stub function is created and address
1322 // of olt_cfg is passed. This is one-of case where we need to test add specific
1323 // code in production code.
1324 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
1325 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001326 err = bcmolt_cfg_get(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001327 #endif
1328 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001329 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query OLT\n");
1330 return bcm_to_grpc_err(err, "cfg: Failed to query OLT");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001331 }
1332
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001333 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
1334 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001335
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001336 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
1337 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001338 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001339
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001340 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
1341 num_of_nni_ports,
1342 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001343 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001344
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001345 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1346 dev_key.device_id = devid;
1347 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1348 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1349 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1350 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
1351 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001352 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001353 OPENOLT_LOG(ERROR, openolt_log_id, "device: Failed to query OLT\n");
1354 return bcm_to_grpc_err(err, "device: Failed to query OLT");
1355 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001356
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001357 std::string bal_version;
1358 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1359 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1360 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
1361 firmware_version = "BAL." + bal_version + "__" + firmware_version;
1362
1363 switch(dev_cfg.data.system_mode) {
1364 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1365 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1366 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1367 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1368 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1369 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1370 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1371 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1372 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1373 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1374 }
1375
1376 switch(dev_cfg.data.chip_family) {
1377 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X_: chip_family = "Maple"; break;
1378 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X_: chip_family = "Aspen"; break;
1379 }
1380
1381 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s object model: %d, family: %s, board_technology: %s\n",
1382 devid, BCM_MAX_PONS_PER_DEV, bal_version.c_str(), BAL_API_VERSION, chip_family.c_str(), board_technology.c_str());
1383
1384 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001385 }
1386
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001387 return Status::OK;
1388}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001389#if 0
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001390Status ProbePonIfTechnology_() {
1391 // Probe maximum extent possible as configured into BAL driver to determine
1392 // which are active in the current BAL topology. And for those
1393 // that are active, determine each port's access technology, i.e. "gpon" or "xgspon".
1394 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001395 bcmolt_pon_interface_cfg interface_obj;
1396 bcmolt_pon_interface_key interface_key;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001397
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001398 interface_key.pon_ni = intf_id;
1399 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001400 if (board_technology == "XGS-PON"
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001401 BCMOLT_MSG_FIELD_GET(&interface_obj, xgs_ngpon2_trx);
1402 else if (board_technology == "GPON")
1403 BCMOLT_MSG_FIELD_GET(&interface_obj, gpon_trx);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001404
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001405 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001406 if (err != BCM_ERR_OK) {
Craig Lutgenb2601f02018-10-23 13:04:31 -05001407 intf_technologies[intf_id] = UNKNOWN_TECH;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001408 if(err != BCM_ERR_RANGE) OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get PON config: %d err %d\n", intf_id, err);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001409 }
1410 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001411 if (board_technology == "XGS-PON") {
1412 switch(interface_obj.data.xgpon_trx.transceiver_type) {
1413 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_PC:
1414 case BCMOLT_XGPON_TRX_TYPE_WTD_RTXM266_702:
1415 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_BC_PLUS:
1416 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_PC:
1417 case BCMOLT_XGPON_TRX_TYPE_LTH_5302_PC:
1418 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_A_PC_PLUS:
1419 case BCMOLT_XGPON_TRX_TYPE_D272RR_SSCB_DM:
1420 intf_technologies[intf_id] = "XGS-PON";
1421 break;
1422 }
1423 } else if (board_technology == "GPON") {
1424 switch(interface_obj.data.gpon_trx.transceiver_type) {
1425 case BCMOLT_TRX_TYPE_SPS_43_48_H_HP_CDE_SD_2013:
1426 case BCMOLT_TRX_TYPE_LTE_3680_M:
1427 case BCMOLT_TRX_TYPE_SOURCE_PHOTONICS:
1428 case BCMOLT_TRX_TYPE_LTE_3680_P_TYPE_C_PLUS:
1429 case BCMOLT_TRX_TYPE_LTE_3680_P_BC:
1430 intf_technologies[intf_id] = "GPON";
1431 break;
1432 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001433 }
Craig Lutgenb2601f02018-10-23 13:04:31 -05001434
1435 if (board_technology != UNKNOWN_TECH) {
1436 board_technology = intf_technologies[intf_id];
1437 } else if (board_technology != MIXED_TECH && board_technology != intf_technologies[intf_id]) {
1438 intf_technologies[intf_id] = MIXED_TECH;
1439 }
1440
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001441 }
1442 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001443 return Status::OK;
1444}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001445#endif
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001446unsigned NumNniIf_() {return num_of_nni_ports;}
1447unsigned NumPonIf_() {return num_of_pon_ports;}
1448
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001449bcmos_errno get_nni_interface_status(bcmolt_interface id, bcmolt_interface_state *state) {
1450 bcmos_errno err;
1451 bcmolt_nni_interface_key nni_key;
1452 bcmolt_nni_interface_cfg nni_cfg;
1453 nni_key.id = id;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001454
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001455 BCMOLT_CFG_INIT(&nni_cfg, nni_interface, nni_key);
1456 BCMOLT_FIELD_SET_PRESENT(&nni_cfg.data, nni_interface_cfg_data, state);
1457 err = bcmolt_cfg_get(dev_id, &nni_cfg.hdr);
1458 *state = nni_cfg.data.state;
1459 return err;
1460}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001461
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001462Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
1463 bcmos_errno err = BCM_ERR_OK;
1464 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1465 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1466 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001467
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001468 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001469 if (err == BCM_ERR_OK) {
1470 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001471 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001472 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1473 CreateDefaultSched(intf_id, upstream);
1474 CreateDefaultQueue(intf_id, upstream);
1475 return Status::OK;
1476 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1477 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1478 return Status::OK;
1479 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001480 }
1481
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001482 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1483 if (set_state) {
1484 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1485 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1486 } else {
1487 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1488 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1489 }
1490 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1491 if (err != BCM_ERR_OK) {
1492 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err %d\n",
1493 (set_state)?"enable":"disable", intf_id, err);
1494 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1495 }
1496 else {
1497 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1498 if (set_state) {
1499 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1500 CreateDefaultSched(intf_id, upstream);
1501 CreateDefaultQueue(intf_id, upstream);
1502 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001503 }
1504
1505 return Status::OK;
1506}
1507
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001508Status DisablePonIf_(uint32_t intf_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001509 bcmolt_pon_interface_cfg interface_obj;
1510 bcmolt_pon_interface_key interface_key;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001511
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001512 interface_key.pon_ni = intf_id;
1513 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
1514 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1515 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001516 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001517 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", intf_id);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001518 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001519 }
1520
1521 return Status::OK;
1522}
1523
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001524Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001525 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001526 bcmos_errno err = BCM_ERR_OK;
1527 bcmolt_onu_cfg onu_cfg;
1528 bcmolt_onu_key onu_key;
1529 bcmolt_serial_number serial_number; /**< ONU serial number */
1530 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001531
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001532 onu_key.onu_id = onu_id;
1533 onu_key.pon_ni = intf_id;
1534 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1535 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1536 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001537 if (err == BCM_ERR_OK) {
1538 if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING ||
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001539 onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) ||
1540 (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_INACTIVE &&
1541 onu_cfg.data.onu_old_state == BCMOLT_ONU_STATE_NOT_CONFIGURED))
1542 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001543 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001544
1545 OPENOLT_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001546vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001547 vendor_specific_to_str(vendor_specific).c_str(), pir);
1548
1549 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1550 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1551 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1552 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1553 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1554 /*set burst and data profiles to fec disabled*/
1555 if (board_technology == "XGS-PON") {
1556 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1557 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1558 } else if (board_technology == "GPON") {
1559 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1560 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1561 }
1562 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1563 if (err != BCM_ERR_OK) {
1564 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to set activate ONU %d on PON %d, err %d\n", onu_id, intf_id, err);
1565 return bcm_to_grpc_err(err, "Failed to activate ONU");
1566 }
1567
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001568 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001569}
1570
Jonathan Davis70c21812018-07-19 15:32:10 -04001571Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1572 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001573 bcmos_errno err = BCM_ERR_OK;
1574 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1575 bcmolt_onu_cfg onu_cfg;
1576 bcmolt_onu_key onu_key; /**< Object key. */
1577 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001578
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001579 onu_key.onu_id = onu_id;
1580 onu_key.pon_ni = intf_id;
1581 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1582 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1583 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001584 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001585 switch (onu_state) {
1586 case BCMOLT_ONU_OPERATION_ACTIVE:
1587 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001588 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001589 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1590 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1591 if (err != BCM_ERR_OK) {
1592 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to \
1593deactivate ONU %d on PON %d, err %d\n", onu_id, intf_id, err);
1594 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1595 }
1596 break;
1597 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001598 }
1599
1600 return Status::OK;
1601}
1602
1603Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001604 const char *vendor_id, const char *vendor_specific) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001605
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001606 OPENOLT_LOG(INFO, openolt_log_id, "DeleteOnu ONU %d on PON %d : vendor id %s, vendor specific %s\n",
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001607 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1608
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001609 // Need to deactivate before removing it (BAL rules)
1610
1611 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1612 // Sleep to allow the state to propagate
1613 // We need the subscriber terminal object to be admin down before removal
1614 // Without sleep the race condition is lost by ~ 20 ms
1615 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1616
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001617 // TODO: Delete the schedulers and queues.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001618
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001619 bcmolt_onu_cfg cfg_obj;
1620 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001621
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001622 OPENOLT_LOG(INFO, openolt_log_id, "Processing subscriber terminal cfg clear for sub_term_id %d and intf_id %d\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001623 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001624
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001625 key.onu_id = onu_id;
1626 key.pon_ni = intf_id;
1627 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001628
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001629 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001630 if (err != BCM_ERR_OK)
1631 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001632 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL subscriber_terminal_id %d, Interface ID %d\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001633 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001634 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1635 }
1636
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001637 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001638}
1639
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001640#define MAX_CHAR_LENGTH 20
1641#define MAX_OMCI_MSG_LENGTH 44
1642Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001643 bcmolt_bin_str buf = {};
1644 bcmolt_onu_cpu_packets omci_cpu_packets;
1645 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001646
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001647 key.pon_ni = intf_id;
1648 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001649
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001650 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1651 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1652 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001653
1654 // ???
1655 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1656 buf.len = MAX_OMCI_MSG_LENGTH;
1657 } else {
1658 buf.len = pkt.size()/2;
1659 }
1660
1661 /* Send the OMCI packet using the BAL remote proxy API */
1662 uint16_t idx1 = 0;
1663 uint16_t idx2 = 0;
1664 uint8_t arraySend[buf.len];
1665 char str1[MAX_CHAR_LENGTH];
1666 char str2[MAX_CHAR_LENGTH];
1667 memset(&arraySend, 0, buf.len);
1668
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001669 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1670 sprintf(str1,"%c", pkt[idx1]);
1671 sprintf(str2,"%c", pkt[++idx1]);
1672 strcat(str1,str2);
1673 arraySend[idx2] = strtol(str1, NULL, 16);
1674 }
1675
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001676 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1677 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001678
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001679 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1680 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1681 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001682
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001683 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001684 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001685 OPENOLT_LOG(ERROR, omci_log_id, "Error sending OMCI message to ONU %d on PON %d\n", onu_id, intf_id);
1686 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001687 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001688 OPENOLT_LOG(DEBUG, omci_log_id, "OMCI request msg of length %d sent to ONU %d on PON %d : %s\n",
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001689 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001690 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001691 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001692
1693 return Status::OK;
1694}
1695
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001696Status OnuPacketOut_(uint32_t intf_id, uint32_t onu_id, uint32_t port_no, uint32_t gemport_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001697 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1698 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1699 bcmolt_bin_str buf = {};
1700 bcmolt_gem_port_id gem_port_id_array[1];
1701 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001702
Craig Lutgen967a1d02018-11-27 10:41:51 -06001703 if (port_no > 0) {
1704 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001705 if (gemport_id == 0) {
1706 bcmos_fastlock_lock(&data_lock);
1707 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1708 // Pick any flow that is mapped with the same port_no.
1709 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1710 if (it != port_to_flows.end() && !it->second.empty()) {
1711 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1712 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1713 if (fit != flowid_to_gemport.end()) {
1714 found = true;
1715 gemport_id = fit->second;
1716 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001717 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001718 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001719
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001720 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001721 OPENOLT_LOG(ERROR, openolt_log_id, "Packet out failed to find destination for ONU %d port_no %u on PON %d\n",
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001722 onu_id, port_no, intf_id);
1723 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1724 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001725 OPENOLT_LOG(INFO, openolt_log_id, "Gem port %u found for ONU %d port_no %u on PON %d\n",
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001726 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001727 }
1728
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001729 gem_port_id_array[0] = gemport_id;
1730 gem_port_list.len = 1;
1731 gem_port_list.arr = gem_port_id_array;
1732 buf.len = pkt.size();
1733 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1734 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1735
1736 /* init the API struct */
1737 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1738 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1739 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1740 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1741 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1742
1743 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1744 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1745
1746 /* call API */
1747 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001748 }
1749 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001750 //TODO: Port No is 0, it is coming sender requirement.
1751 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1752 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001753 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001754 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001755
1756 return Status::OK;
1757}
1758
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001759Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001760 bcmolt_flow_key key = {}; /* declare key */
1761 bcmolt_bin_str buffer = {};
1762 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001763
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001764 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1765 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001766
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001767 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1768 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1769 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1770 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1771 key.flow_id = flow_id;
1772 else {
1773 if (flow_id_counters != 0) {
1774 for (int flowid=0; flowid < flow_id_counters; flowid++) {
1775 int flow_index = flow_id_data[flowid][0];
1776 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1777 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1778 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1779 key.flow_id = flow_index;
1780 break;
1781 }
1782 }
1783 }
1784 else {
1785 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1786 }
1787 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001788
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001789 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001790
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001791 /* Initialize the API struct. */
1792 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001793
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001794 buffer.len = pkt.size();
1795 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1796 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1797 if (buffer.arr == NULL) {
1798 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1799 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1800 }
1801 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1802
1803 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1804 if (err) {
1805 OPENOLT_LOG(ERROR, openolt_log_id, "Error sending packets via nni port %d, flow_id %d err %d\n", intf_id, key.flow_id, err);
1806 } else {
1807 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1808 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001809
1810 return Status::OK;
1811}
1812
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001813uint32_t GetPortNum_(uint32_t flow_id) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001814 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001815 uint32_t port_no = 0;
1816 std::map<uint32_t, uint32_t >::const_iterator it = flowid_to_port.find(flow_id);
1817 if (it != flowid_to_port.end()) {
1818 port_no = it->second;
1819 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001820 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001821 return port_no;
1822}
1823
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001824#define FLOW_LOG(level,msg,err) \
1825 do { \
1826 OPENOLT_LOG(level, openolt_log_id, "--------> %s (flow_id %d) err: %d <--------\n", msg, key.flow_id, err); \
1827 OPENOLT_LOG(level, openolt_log_id, "intf_id %d, onu_id %d, uni_id %d, port_no %u, cookie %"PRIu64"\n", \
1828 access_intf_id, onu_id, uni_id, port_no, cookie); \
1829 OPENOLT_LOG(level, openolt_log_id, "flow_type %s, queue_id %d, sched_id %d\n", flow_type.c_str(), \
1830 cfg.data.egress_qos.u.fixed_queue.queue_id, cfg.data.egress_qos.tm_sched.id); \
1831 OPENOLT_LOG(level, openolt_log_id, "Ingress(intfd_type %s, intf_id %d), Egress(intf_type %s, intf_id %d)\n", \
1832 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), cfg.data.ingress_intf.intf_id, \
1833 GET_FLOW_INTERFACE_TYPE(cfg.data.egress_intf.intf_type), cfg.data.egress_intf.intf_id); \
1834 OPENOLT_LOG(level, openolt_log_id, "classifier(o_vid %d, o_pbits %d, i_vid %d, i_pbits %d, ether type 0x%x)\n", \
1835 c_val.o_vid, c_val.o_pbits, c_val.i_vid, c_val.i_pbits, classifier.eth_type()); \
1836 OPENOLT_LOG(level, openolt_log_id, "classifier(ip_proto 0x%x, gemport_id %d, src_port %d, dst_port %d, pkt_tag_type %s)\n", \
1837 c_val.ip_proto, gemport_id, c_val.src_port, c_val.dst_port, GET_PKT_TAG_TYPE(c_val.pkt_tag_type)); \
1838 OPENOLT_LOG(level, openolt_log_id, "action(cmds_bitmask %s, o_vid %d, o_pbits %d, i_vid %d, i_pbits %d)\n\n", \
1839 get_flow_acton_command(a_val.cmds_bitmask), a_val.o_vid, a_val.o_pbits, a_val.i_vid, a_val.i_pbits); \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001840 } while(0)
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001841
1842#define FLOW_PARAM_LOG() \
1843 do { \
1844 OPENOLT_LOG(INFO, openolt_log_id, "--------> flow comparison (now before) <--------\n"); \
1845 OPENOLT_LOG(INFO, openolt_log_id, "flow_id (%d %d)\n", \
1846 key.flow_id, flow_index); \
1847 OPENOLT_LOG(INFO, openolt_log_id, "onu_id (%d %lu)\n", \
1848 cfg.data.onu_id , get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)); \
1849 OPENOLT_LOG(INFO, openolt_log_id, "type (%d %lu)\n", \
1850 key.flow_type, get_flow_status(flow_index, flow_id_data[flowid][1], FLOW_TYPE)); \
1851 OPENOLT_LOG(INFO, openolt_log_id, "svc_port_id (%d %lu)\n", \
1852 cfg.data.svc_port_id, get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)); \
1853 OPENOLT_LOG(INFO, openolt_log_id, "priority (%d %lu)\n", \
1854 cfg.data.priority, get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)); \
1855 OPENOLT_LOG(INFO, openolt_log_id, "cookie (%lu %lu)\n", \
1856 cfg.data.cookie, get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)); \
1857 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf_type (%s %s)\n", \
1858 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), \
1859 GET_FLOW_INTERFACE_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE))); \
1860 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf id (%d %lu)\n", \
1861 cfg.data.ingress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)); \
1862 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_type (%d %lu)\n", \
1863 cfg.data.egress_intf.intf_type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)); \
1864 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_id (%d %lu)\n", \
1865 cfg.data.egress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)); \
1866 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_vid (%d %lu)\n", \
1867 c_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)); \
1868 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_pbits (%d %lu)\n", \
1869 c_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)); \
1870 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_vid (%d %lu)\n", \
1871 c_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)); \
1872 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_pbits (%d %lu)\n", \
1873 c_val.i_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)); \
1874 OPENOLT_LOG(INFO, openolt_log_id, "classifier ether_type (0x%x 0x%lx)\n", \
1875 c_val.ether_type , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)); \
1876 OPENOLT_LOG(INFO, openolt_log_id, "classifier ip_proto (%d %lu)\n", \
1877 c_val.ip_proto , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)); \
1878 OPENOLT_LOG(INFO, openolt_log_id, "classifier src_port (%d %lu)\n", \
1879 c_val.src_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)); \
1880 OPENOLT_LOG(INFO, openolt_log_id, "classifier dst_port (%d %lu)\n", \
1881 c_val.dst_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)); \
1882 OPENOLT_LOG(INFO, openolt_log_id, "classifier pkt_tag_type (%s %s)\n", \
1883 GET_PKT_TAG_TYPE(c_val.pkt_tag_type), \
1884 GET_PKT_TAG_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE))); \
1885 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos type (%d %lu)\n", \
1886 cfg.data.egress_qos.type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)); \
1887 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos queue_id (%d %lu)\n", \
1888 cfg.data.egress_qos.u.fixed_queue.queue_id, \
1889 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)); \
1890 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos sched_id (%d %lu)\n", \
1891 cfg.data.egress_qos.tm_sched.id, \
1892 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)); \
1893 OPENOLT_LOG(INFO, openolt_log_id, "classifier cmds_bitmask (%s %s)\n", \
1894 get_flow_acton_command(a_val.cmds_bitmask), \
1895 get_flow_acton_command(get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_CMDS_BITMASK))); \
1896 OPENOLT_LOG(INFO, openolt_log_id, "action o_vid (%d %lu)\n", \
1897 a_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)); \
1898 OPENOLT_LOG(INFO, openolt_log_id, "action i_vid (%d %lu)\n", \
1899 a_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)); \
1900 OPENOLT_LOG(INFO, openolt_log_id, "action o_pbits (%d %lu)\n", \
1901 a_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)); \
1902 OPENOLT_LOG(INFO, openolt_log_id, "action i_pbits (%d %lu)\n\n", \
1903 a_val.i_pbits, get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)); \
1904 } while(0)
1905
1906#define FLOW_CHECKER
1907//#define SHOW_FLOW_PARAM
1908
Craig Lutgen967a1d02018-11-27 10:41:51 -06001909Status FlowAdd_(int32_t access_intf_id, int32_t onu_id, int32_t uni_id, uint32_t port_no,
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001910 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001911 int32_t alloc_id, int32_t network_intf_id,
1912 int32_t gemport_id, const ::openolt::Classifier& classifier,
Craig Lutgen967a1d02018-11-27 10:41:51 -06001913 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001914 bcmolt_flow_cfg cfg;
1915 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001916 int32_t o_vid = -1;
1917 bool single_tag = false;
1918 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001919 bcmolt_classifier c_val = { };
1920 bcmolt_action a_val = { };
1921 bcmolt_tm_queue_ref tm_val = { };
1922 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001923 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001924
1925 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001926 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001927 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001928 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001929 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001930 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001931 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001932 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001933 }
1934
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001935 BCMOLT_CFG_INIT(&cfg, flow, key);
1936 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001937
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001938 if (access_intf_id >= 0 && network_intf_id >= 0) {
1939 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1940 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1941 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
1942 if (classifier.eth_type() == EAP_ETHER_TYPE || //EAPOL packet
1943 (classifier.ip_proto() == 17 && classifier.src_port() == 68 && classifier.dst_port() == 67)) { //DHCP packet
1944 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
1945 } else {
1946 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1947 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
1948 }
1949 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1950 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1951 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1952 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1953 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
1954 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301955 } else if (access_intf_id < 0 ) {
1956 // This is the case for packet trap from NNI flow.
1957 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1958 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1959 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001960 } else {
1961 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1962 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
1963 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001964
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301965
Shad Ansari39739bc2018-09-13 21:38:37 +00001966 if (onu_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001967 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001968 }
1969 if (gemport_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001970 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001971 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001972 if (gemport_id >= 0 && port_no != 0) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001973 bcmos_fastlock_lock(&data_lock);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001974 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001975 port_to_flows[port_no].insert(key.flow_id);
1976 flowid_to_gemport[key.flow_id] = gemport_id;
1977 }
1978 else
1979 {
1980 flowid_to_port[key.flow_id] = port_no;
1981 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001982 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001983 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001984 if (priority_value >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001985 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
Shad Ansari39739bc2018-09-13 21:38:37 +00001986 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001987
1988 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001989 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001990 if (classifier.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001991 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_tpid 0x%04x\n", classifier.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05001992 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_tpid, classifier.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001993 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001994 */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001995 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001996 if (classifier.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001997 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_tpid 0x%04x\n", classifier.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05001998 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_tpid, classifier.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001999 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002000 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002001
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002002 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002003 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002004 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
2005 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002006 }
2007
2008 /*
2009 if (classifier.dst_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002010 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_mac, classifier.dst_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002011 }
2012
2013 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002014 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002015 }
2016 */
2017
2018 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002019 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
2020 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002021 }
2022
2023 /*
2024 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002025 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002026 }
2027
2028 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002029 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002030 }
2031 */
2032
2033 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002034 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
2035 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002036 }
2037
2038 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002039 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
2040 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002041 }
2042
2043 if (!classifier.pkt_tag_type().empty()) {
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302044 if (cfg.data.ingress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_NNI && \
2045 cfg.data.egress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
2046 // This is case where packet traps from NNI port. As per Broadcom workaround
2047 // suggested in CS8839882, the packet_tag_type has to be 'untagged' irrespective
2048 // of what the actual tag type is. Otherwise, packet trap from NNI wont work.
2049 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2050 } else {
2051 if (classifier.o_vid()) {
2052 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
2053 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
2054 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002055
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302056 if (classifier.i_vid()) {
2057 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
2058 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
2059 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002060
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302061 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
2062 if (classifier.pkt_tag_type().compare("untagged") == 0) {
2063 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2064 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
2065 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
2066 single_tag = true;
2067
2068 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
2069 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2070 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
2071 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
2072
2073 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
2074 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2075 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002076 }
2077 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002078 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002079 }
2080
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002081 if (cfg.data.egress_intf.intf_type != BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002082 const ::openolt::ActionCmd& cmd = action.cmd();
2083
2084 if (cmd.add_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002085 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
2086 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002087 }
2088
2089 if (cmd.remove_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002090 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
2091 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002092 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002093 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002094 if (cmd.trap_to_host()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002095 OPENOLT_LOG(INFO, openolt_log_id, "action trap-to-host\n");
Craig Lutgen19512312018-11-02 10:14:46 -05002096 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002097 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002098 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002099 if (action.o_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002100 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002101 o_vid = action.o_vid();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002102 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002103 }
2104
2105 if (action.o_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002106 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
2107 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002108 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002109 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002110 if (action.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002111 OPENOLT_LOG(INFO, openolt_log_id, "action o_tpid=0x%04x\n", action.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002112 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_tpid, action.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002113 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002114 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002115 if (action.i_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002116 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
2117 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002118 }
2119
2120 if (action.i_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002121 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
2122 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002123 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002124 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002125 if (action.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002126 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_tpid=0x%04x\n", action.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002127 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_tpid, action.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002128 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002129 */
2130 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002131 }
2132
Shad Ansari39739bc2018-09-13 21:38:37 +00002133 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002134 if(single_tag && ether_type == EAP_ETHER_TYPE) {
2135 tm_val.sched_id = (flow_type.compare(upstream) == 0) ? \
2136 get_default_tm_sched_id(network_intf_id, upstream) : \
2137 get_default_tm_sched_id(access_intf_id, downstream);
2138 tm_val.queue_id = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002139
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002140 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2141 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2142 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002143
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002144 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2145 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2146 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2147 } else {
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002148 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002149 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
2150 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
2151
2152 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2153 // Queue 0 on DS subscriber scheduler
2154 tm_val.queue_id = 0;
2155
2156 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2157 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2158 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2159
2160 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2161 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2162 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2163
2164 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2165 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2166 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2167
2168 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2169 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2170 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2171 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2172
2173 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2174 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2175 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2176 }
2177 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2178 // NNI Scheduler ID
2179 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2180 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2181 // Queue 0 on NNI scheduler
2182 tm_val.queue_id = 0;
2183 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2184 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2185 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2186
2187 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2188 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2189 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2190
2191 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2192 /* Fetch TM QMP ID mapped to US NNI scheduler */
2193 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2194 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2195 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2196 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2197 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2198
2199 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2200 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2201 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2202 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002203 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002204 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302205 } else {
2206 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2207 tm_val.queue_id = 0;
2208
2209 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2210 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2211 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2212
2213 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2214 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2215 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002216 }
2217
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002218 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
2219 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2220#ifdef FLOW_CHECKER
2221 //Flow Checker, To avoid duplicate flow.
2222 if (flow_id_counters != 0) {
2223 bool b_duplicate_flow = false;
2224 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2225 int flow_index = flow_id_data[flowid][0];
2226 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)) && \
2227 (key.flow_type == flow_id_data[flowid][1]) && \
2228 (cfg.data.svc_port_id == get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)) && \
2229 (cfg.data.priority == get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)) && \
2230 (cfg.data.cookie == get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)) && \
2231 (cfg.data.ingress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE)) && \
2232 (cfg.data.ingress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)) && \
2233 (cfg.data.egress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)) && \
2234 (cfg.data.egress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)) && \
2235 (c_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)) && \
2236 (c_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)) && \
2237 (c_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)) && \
2238 (c_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)) && \
2239 (c_val.ether_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)) && \
2240 (c_val.ip_proto == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)) && \
2241 (c_val.src_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)) && \
2242 (c_val.dst_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)) && \
2243 (c_val.pkt_tag_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE)) && \
2244 (cfg.data.egress_qos.type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)) && \
2245 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)) && \
2246 (cfg.data.egress_qos.tm_sched.id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)) && \
2247 (a_val.cmds_bitmask == get_flow_status(flowid, flow_id_data[flowid][1], ACTION_CMDS_BITMASK)) && \
2248 (a_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)) && \
2249 (a_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)) && \
2250 (a_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)) && \
2251 (a_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)) && \
2252 (cfg.data.state == get_flow_status(flowid, flow_id_data[flowid][1], STATE));
2253#ifdef SHOW_FLOW_PARAM
2254 // Flow Parameter
2255 FLOW_PARAM_LOG();
2256#endif
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002257
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002258 if (b_duplicate_flow) {
2259 FLOW_LOG(WARNING, "Flow duplicate", 0);
2260 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2261 }
2262 }
2263 }
2264#endif
2265
2266 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2267 if (err) {
2268 FLOW_LOG(ERROR, "Flow add failed", err);
2269 return bcm_to_grpc_err(err, "flow add failed");
2270 } else {
2271 FLOW_LOG(INFO, "Flow add ok", err);
2272 bcmos_fastlock_lock(&data_lock);
2273 flow_id_data[flow_id_counters][0] = key.flow_id;
2274 flow_id_data[flow_id_counters][1] = key.flow_type;
2275 flow_id_counters += 1;
2276 bcmos_fastlock_unlock(&data_lock, 0);
2277 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002278
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002279 return Status::OK;
2280}
2281
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002282Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2283
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002284 bcmolt_flow_cfg cfg;
2285 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002286
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002287 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002288 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002289 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002290 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002291 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002292 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002293 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002294 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002295 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2296 }
2297
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002298 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002299 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002300 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002301 flowid_to_gemport.erase(key.flow_id);
2302 port_to_flows[port_no].erase(key.flow_id);
2303 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2304 }
2305 else
2306 {
2307 flowid_to_port.erase(key.flow_id);
2308 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002309 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002310
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002311 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002312
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002313 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002314 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002315 OPENOLT_LOG(ERROR, openolt_log_id, "Error %d while removing flow %d, %s\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04002316 err, flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002317 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2318 }
2319
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002320 bcmos_fastlock_lock(&data_lock);
2321 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2322 if (flow_id_data[flowid][0] == flow_id && flow_id_data[flowid][1] == key.flow_type) {
2323 flow_id_counters -= 1;
2324 for (int i=flowid; i < flow_id_counters; i++) {
2325 flow_id_data[i][0] = flow_id_data[i + 1][0];
2326 flow_id_data[i][1] = flow_id_data[i + 1][1];
2327 }
2328 break;
2329 }
2330 }
2331 bcmos_fastlock_unlock(&data_lock, 0);
2332
2333 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002334 return Status::OK;
2335}
2336
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002337bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2338 bcmos_errno err;
2339 bcmolt_tm_sched_cfg tm_sched_cfg;
2340 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2341 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2342
Jason Huangbf45ffb2019-10-30 17:29:02 +08002343 //check TM scheduler has configured or not
2344 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2345 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
2346 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
2347 if (err) {
2348 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query TM scheduler\n");
2349 return err;
2350 }
2351 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2352 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2353 return BCM_ERR_OK;
2354 }
2355
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002356 // bcmbal_tm_sched_owner
2357 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2358
2359 /**< The output of the tm_sched object instance */
2360 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2361
2362 if (direction.compare(upstream) == 0) {
2363 // In upstream it is NNI scheduler
2364 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2365 } else if (direction.compare(downstream) == 0) {
2366 // In downstream it is PON scheduler
2367 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2368 }
2369
2370 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2371
2372 // bcmbal_tm_sched_type
2373 // set the deafult policy to strict priority
2374 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2375
2376 // num_priorities: Max number of strict priority scheduling elements
2377 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
2378
2379 // bcmbal_tm_shaping
2380 uint32_t cir = 1000000;
2381 uint32_t pir = 1000000;
2382 uint32_t burst = 65536;
2383 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in %s pir=%u, burst=%u\n",
2384 direction.c_str(), pir, burst);
2385 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2386 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2387 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2388 // BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2389 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2390 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
2391
2392 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2393 if (err) {
2394 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err %d\n", \
2395 direction.c_str(), tm_sched_key.id, intf_id, err);
2396 return err;
2397 }
2398
2399 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2400 direction.c_str(), tm_sched_key.id, intf_id);
2401 return BCM_ERR_OK;
2402}
2403
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002404bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
2405 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2406 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002407
2408 bcmos_errno err;
2409
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002410 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002411 bcmolt_tm_sched_cfg tm_sched_cfg;
2412 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2413 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002414
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002415 // bcmbal_tm_sched_owner
2416 // In downstream it is sub_term scheduler
2417 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002418
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002419 /**< The output of the tm_sched object instance */
2420 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002421
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002422 // bcmbal_tm_sched_parent
2423 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2424 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2425 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_param.u.priority.priority, priority);
2426 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
2427 be achieved using the' virtual' type of attachment.
2428 tm_sched_owner.u.sub_term.intf_id = intf_id;
2429 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2430 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002431
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002432 // bcmbal_tm_sched_type
2433 // set the deafult policy to strict priority
2434 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002435
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002436 // num_priorities: Max number of strict priority scheduling elements
2437 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002438
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002439 // bcmbal_tm_shaping
2440 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2441 uint32_t cir = tf_sh_info.cir();
2442 uint32_t pir = tf_sh_info.pir();
2443 uint32_t burst = tf_sh_info.pbs();
2444 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2445 cir, pir, burst);
2446 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2447 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2448 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2449 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2450 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2451 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002452 }
2453
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002454 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002455 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002456 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
2457intf_id %d, onu_id %d, uni_id %d, port_no %u\n", tm_sched_key.id, intf_id, onu_id, \
2458 uni_id, port_no);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002459 return err;
2460 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002461 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2462uni_id %d, port_no %u\n", tm_sched_key.id, intf_id, onu_id, uni_id, port_no);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002463
2464 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002465 bcmolt_itupon_alloc_cfg cfg;
2466 bcmolt_itupon_alloc_key key = { };
2467 key.pon_ni = intf_id;
2468 key.alloc_id = alloc_id;
2469 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
2470 int pir_bw = tf_sh_info.pir();
2471 int cir_bw = tf_sh_info.cir();
2472 //offset to match bandwidth granularity
2473 int offset_pir_bw = pir_bw%bw_granularity;
2474 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002475
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002476 pir_bw = pir_bw - offset_pir_bw;
2477 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002478
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002479 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002480
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002481 switch (additional_bw) {
2482 case 2: //AdditionalBW_BestEffort
2483 if (pir_bw == 0) {
2484 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2485%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2486 } else if (pir_bw < cir_bw) {
2487 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2488bandwidth (%d)\n", pir_bw, cir_bw);
2489 return BCM_ERR_PARM;
2490 } else if (pir_bw == cir_bw) {
2491 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2492bandwidth for additional bandwidth eligibility of type best_effort\n");
2493 return BCM_ERR_PARM;
2494 }
2495 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2496 break;
2497 case 1: //AdditionalBW_NA
2498 if (pir_bw == 0) {
2499 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2500%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2501 return BCM_ERR_PARM;
2502 } else if (cir_bw == 0) {
2503 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2504additional bandwidth eligibility of type Non-Assured (NA)\n");
2505 return BCM_ERR_PARM;
2506 } else if (pir_bw < cir_bw) {
2507 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2508bandwidth (%d)\n", pir_bw, cir_bw);
2509 return BCM_ERR_PARM;
2510 } else if (pir_bw == cir_bw) {
2511 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2512bandwidth for additional bandwidth eligibility of type non_assured\n");
2513 return BCM_ERR_PARM;
2514 }
2515 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2516 break;
2517 case 0: //AdditionalBW_None
2518 if (pir_bw == 0) {
2519 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
252016000 bytes/sec\n");
2521 return BCM_ERR_PARM;
2522 } else if (cir_bw == 0) {
2523 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2524for additional bandwidth eligibility of type None\n");
2525 return BCM_ERR_PARM;
2526 } else if (pir_bw > cir_bw) {
2527 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2528for additional bandwidth eligibility of type None\n");
2529 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2530bandwidth in None eligibility\n", pir_bw);
2531 cir_bw = pir_bw;
2532 } else if (pir_bw < cir_bw) {
2533 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2534bandwidth (%d)\n", pir_bw, cir_bw);
2535 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2536bandwidth in None eligibility\n", pir_bw);
2537 cir_bw = pir_bw;
2538 }
2539 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2540 break;
2541 default:
2542 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002543 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002544 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2545 in a fine granularity. */
2546 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2547 /* Fixed Bandwidth with no critical requirement of shaping */
2548 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2549 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2550 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2551 /* Maximum allocated bandwidth allowed for this alloc ID */
2552 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2553 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2554 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
2555 for skipped allocations during quiet window */
2556 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2557 /**< Allocation Profile index for CBR non-RT Bandwidth */
2558 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2559 /**< Allocation Profile index for CBR RT Bandwidth */
2560 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2561 /**< Alloc ID Weight used in case of Extended DBA mode */
2562 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2563 /**< Alloc ID Priority used in case of Extended DBA mode */
2564 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2565 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002566
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002567 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002568 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002569 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2570port_no %u, alloc_id %d, err %d\n", intf_id, onu_id,uni_id,port_no,alloc_id, err);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002571 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002572 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002573 OPENOLT_LOG(INFO, openolt_log_id, "Create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d, port_no %u, \
2574alloc_id %d\n", intf_id,onu_id,uni_id,port_no,alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002575 }
2576
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002577 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002578}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002579
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002580Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2581 uint32_t intf_id = traffic_scheds->intf_id();
2582 uint32_t onu_id = traffic_scheds->onu_id();
2583 uint32_t uni_id = traffic_scheds->uni_id();
2584 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002585 std::string direction;
2586 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002587 tech_profile::SchedulerConfig sched_config;
2588 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002589 uint32_t priority;
2590 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002591 tech_profile::SchedulingPolicy sched_policy;
2592 tech_profile::TrafficShapingInfo traffic_shaping_info;
2593 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002594
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002595 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2596 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002597
2598 direction = GetDirection(traffic_sched.direction());
2599 if (direction.compare("direction-not-supported") == 0)
2600 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2601
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002602 alloc_id = traffic_sched.alloc_id();
2603 sched_config = traffic_sched.scheduler();
2604 additional_bw = sched_config.additional_bw();
2605 priority = sched_config.priority();
2606 weight = sched_config.weight();
2607 sched_policy = sched_config.sched_policy();
2608 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2609 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2610 sched_policy, traffic_shaping_info);
2611 if (err) {
2612 return bcm_to_grpc_err(err, "Failed to create scheduler");
2613 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002614 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002615 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002616}
Jonathan Davis70c21812018-07-19 15:32:10 -04002617
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002618bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002619
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002620 bcmos_errno err;
Jonathan Davis70c21812018-07-19 15:32:10 -04002621
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002622 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002623 bcmolt_itupon_alloc_cfg cfg;
2624 bcmolt_itupon_alloc_key key = { };
2625 key.pon_ni = intf_id;
2626 key.alloc_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002627
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002628 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
2629 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2630 if (err) {
2631 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler sched, direction = %s, intf_id %d, alloc_id %d, err %d\n", \
2632 direction.c_str(), intf_id, alloc_id, err);
2633 return err;
2634 }
2635 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, intf_id %d, alloc_id %d\n", \
2636 direction.c_str(), intf_id, alloc_id);
2637 } else if (direction == downstream) {
2638 bcmolt_tm_sched_cfg cfg;
2639 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002640
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002641 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
2642 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2643 } else {
2644 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2645 return BCM_ERR_OK;
2646 }
2647 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2648 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2649 if (err) {
2650 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, id %d, intf_id %d, onu_id %d\n", \
2651 direction.c_str(), key.id, intf_id, onu_id);
2652 return err;
2653 }
2654 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n", \
2655 direction.c_str(), key.id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002656 }
2657
2658 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002659 return BCM_ERR_OK;
2660}
2661
2662Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2663 uint32_t intf_id = traffic_scheds->intf_id();
2664 uint32_t onu_id = traffic_scheds->onu_id();
2665 uint32_t uni_id = traffic_scheds->uni_id();
2666 std::string direction;
2667 bcmos_errno err;
2668
2669 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2670 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002671
2672 direction = GetDirection(traffic_sched.direction());
2673 if (direction.compare("direction-not-supported") == 0)
2674 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2675
2676 int alloc_id = traffic_sched.alloc_id();
2677 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002678 if (err) {
2679 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2680 }
2681 }
2682 return Status::OK;
2683}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002684
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002685bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2686 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002687 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002688 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2689 bcmolt_tm_qmp_key tm_qmp_key;
2690 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002691
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002692 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2693 if (tm_qmp_id == -1) {
2694 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed profile count is 16.\n");
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002695 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002696
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002697 tm_qmp_key.id = tm_qmp_id;
2698 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2699 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2700 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002701
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002702 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2703 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2704 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
2705 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2706 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002707
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002708 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002709 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002710 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, id %d\n", \
2711 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002712 return err;
2713 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002714
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002715 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2716 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002717 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002718}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002719
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002720bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2721 bcmos_errno err;
2722 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2723 bcmolt_tm_qmp_key tm_qmp_key;
2724 tm_qmp_key.id = tm_qmp_id;
2725
2726 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2727 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2728 if (err) {
2729 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, id %d\n", \
2730 tm_qmp_key.id);
2731 return err;
2732 }
2733
2734 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2735 tm_qmp_key.id);
2736 return BCM_ERR_OK;
2737}
2738
2739bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2740 bcmos_errno err;
2741
2742 /* Create 4 Queues on given PON/NNI scheduler */
2743 for (int queue_id = 0; queue_id < 4; queue_id++) {
2744 bcmolt_tm_queue_cfg tm_queue_cfg;
2745 bcmolt_tm_queue_key tm_queue_key = {};
2746 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2747 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002748 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2749 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2750 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002751
2752 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2753 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2754 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2755
2756 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2757 if (err) {
2758 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s tm queue, id %d, sched_id %d, tm_q_set_id %d\n", \
2759 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2760 return err;
2761 }
2762
2763 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2764 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2765 }
2766 return BCM_ERR_OK;
2767}
2768
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002769bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2770 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002771 bcmos_errno err;
2772 bcmolt_tm_queue_cfg cfg;
2773 bcmolt_tm_queue_key key = { };
2774 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
2775gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
2776
2777 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2778 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2779
2780 if (priority > 7) {
2781 return BCM_ERR_RANGE;
2782 }
2783
2784 /* FIXME: The upstream queues have to be created once only.
2785 The upstream queues on the NNI scheduler are shared by all subscribers.
2786 When the first scheduler comes in, the queues get created, and are re-used by all others.
2787 Also, these queues should be present until the last subscriber exits the system.
2788 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2789
2790 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2791 for each GEM in TECH PROFILE */
2792 key.id = queue_id_list[priority];
2793
2794 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2795 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2796 key.id = 0;
2797 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2798 }
2799 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2800 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2801 }
2802 else {
2803 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2804 }
2805
2806 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2807
2808 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2809 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2810
2811 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2812 if (err) {
2813 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, id %d, \
2814sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err %d\n", \
2815 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, err);
2816 return err;
2817 }
2818
2819 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2820intf_id %d, onu_id %d, uni_id %d\n", direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id);
2821 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002822}
2823
2824Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2825 uint32_t intf_id = traffic_queues->intf_id();
2826 uint32_t onu_id = traffic_queues->onu_id();
2827 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002828 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002829 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002830 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002831 bcmolt_egress_qos_type qos_type = get_qos_type(intf_id, onu_id, uni_id, traffic_queues->traffic_queues_size());
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002832
2833 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2834 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2835 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2836 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2837 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2838
2839 direction = GetDirection(traffic_queue.direction());
2840 if (direction.compare("direction-not-supported") == 0)
2841 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2842
2843 queues_priority_q[i] = traffic_queue.priority();
2844 queues_pbit_map[i] = traffic_queue.pbit_map();
2845 }
2846
2847 std::vector<uint32_t> tmq_map_profile(8, 0);
2848 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2849 queues_priority_q, COUNT_OF(queues_priority_q));
2850 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2851 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2852
2853 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2854 if (tm_qmp_id == -1) {
2855 CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2856 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2857 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2858 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2859 }
2860 }
2861
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002862 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2863 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002864
2865 direction = GetDirection(traffic_queue.direction());
2866 if (direction.compare("direction-not-supported") == 0)
2867 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2868
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002869 err = CreateQueue(direction, intf_id, onu_id, uni_id, qos_type, traffic_queue.priority(), traffic_queue.gemport_id());
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002870
Girish Gowdruf26cf882019-05-01 23:47:58 -07002871 // If the queue exists already, lets not return failure and break the loop.
2872 if (err && err != BCM_ERR_ALREADY) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002873 return bcm_to_grpc_err(err, "Failed to create queue");
2874 }
2875 }
2876 return Status::OK;
2877}
2878
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002879bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2880 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002881 bcmolt_tm_queue_cfg cfg;
2882 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002883 bcmos_errno err;
2884
2885 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002886 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
2887 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2888 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002889 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002890 OPENOLT_LOG(INFO, openolt_log_id, "queue not present in DS. Not clearing, access_intf_id %d, onu_id %d, uni_id %d, gemport_id %d, direction %s\n", access_intf_id, onu_id, uni_id, gemport_id, direction.c_str());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002891 return BCM_ERR_OK;
2892 }
2893 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002894 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2895 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002896 return BCM_ERR_OK;
2897 }
2898
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002899 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2900 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2901 // Reset the queue id to 0 when using fixed queue.
2902 key.id = 0;
2903 }
2904 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2905 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2906 }
2907 else {
2908 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2909 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002910
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002911 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2912 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002913 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002914 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, id %d, sched_id %d, \
2915tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d\n",
2916 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002917 return err;
2918 }
2919
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002920 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2921intf_id %d, onu_id %d, uni_id %d\n", direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002922
2923 return BCM_ERR_OK;
2924}
2925
2926Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2927 uint32_t intf_id = traffic_queues->intf_id();
2928 uint32_t onu_id = traffic_queues->onu_id();
2929 uint32_t uni_id = traffic_queues->uni_id();
2930 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002931 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002932 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002933 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002934 bcmolt_egress_qos_type qos_type = get_qos_type(intf_id, onu_id, uni_id, traffic_queues->traffic_queues_size());
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002935
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002936 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2937 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002938
2939 direction = GetDirection(traffic_queue.direction());
2940 if (direction.compare("direction-not-supported") == 0)
2941 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2942
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002943 err = RemoveQueue(direction, intf_id, onu_id, uni_id, qos_type, traffic_queue.priority(), traffic_queue.gemport_id());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002944 if (err) {
2945 return bcm_to_grpc_err(err, "Failed to remove queue");
2946 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002947 }
2948
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002949 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE && (direction.compare(upstream) == 0 || direction.compare(downstream) == 0 && is_tm_sched_id_present(intf_id, onu_id, uni_id, direction))) {
2950 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2951 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2952
2953 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2954 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
2955 RemoveTrafficQueueMappingProfile(tm_qmp_id);
2956 }
2957 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002958 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002959 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002960}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002961
2962Status check_connection() {
2963 int maxTrials = 60;
2964 while (!bcmolt_api_conn_mgr_is_connected(dev_id)) {
2965 sleep(1);
2966 if (--maxTrials == 0)
2967 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check connection failed");
2968 else
2969 OPENOLT_LOG(INFO, openolt_log_id, "waiting for daemon connection ...\n");
2970 }
2971 OPENOLT_LOG(INFO, openolt_log_id, "daemon is connected\n");
2972 return Status::OK;
2973}
2974
2975Status check_bal_ready() {
2976 bcmos_errno err;
2977 int maxTrials = 30;
2978 bcmolt_olt_cfg olt_cfg = { };
2979 bcmolt_olt_key olt_key = { };
2980
2981 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
2982 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
2983
2984 while (olt_cfg.data.bal_state != BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY) {
2985 if (--maxTrials == 0)
2986 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check bal ready failed");
2987 sleep(5);
2988 #ifdef TEST_MODE
2989 // It is impossible to mock the setting of olt_cfg.data.bal_state because
2990 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
2991 // set the olt_cfg.data.bal_state. So a new stub function is created and address
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04002992 // of olt_cfg is passed. This is one-of case where we need to add test specific
2993 // code in production code.
2994 if (bcmolt_cfg_get__bal_state_stub(dev_id, &olt_cfg)) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08002995 #else
2996 if (bcmolt_cfg_get(dev_id, &olt_cfg.hdr)) {
2997 #endif
2998 continue;
2999 }
3000 else
3001 OPENOLT_LOG(INFO, openolt_log_id, "waiting for BAL ready ...\n");
3002 }
3003
3004 OPENOLT_LOG(INFO, openolt_log_id, "BAL is ready\n");
3005 return Status::OK;
3006}