blob: 5053cd38e9867428d5eef2466abcb8c07ed65308 [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
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000106/* Constants used for retrying some BAL APIs */
107const uint32_t BAL_API_RETRY_TIME_IN_USECS = 1000000;
108const uint32_t MAX_BAL_API_RETRY_COUNT = 5;
109
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000110/* Current session */
111static bcmcli_session *current_session;
112static bcmcli_entry *api_parent_dir;
113bcmos_bool status_bcm_cli_quit = BCMOS_FALSE;
114bcmos_task bal_cli_thread;
115const char *bal_cli_thread_name = "bal_cli_thread";
116uint16_t flow_id_counters = 0;
117int flow_id_data[16384][2];
Shad Ansariedef2132018-08-10 22:14:50 +0000118State state;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400119
Craig Lutgen967a1d02018-11-27 10:41:51 -0600120static std::map<uint32_t, uint32_t> flowid_to_port; // For mapping upstream flows to logical ports
121static std::map<uint32_t, uint32_t> flowid_to_gemport; // For mapping downstream flows into gemports
122static 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 -0800123
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000124/* This represents the Key to 'sched_map' map.
125 Represents (pon_intf_id, onu_id, uni_id, direction) */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800126typedef std::tuple<uint32_t, uint32_t, uint32_t, std::string> sched_map_key_tuple;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000127/* 'sched_map' maps sched_map_key_tuple to DBA (Upstream) or
128 Subscriber (Downstream) Scheduler ID */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800129static std::map<sched_map_key_tuple, int> sched_map;
130
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -0500131/* This represents the Key to 'qos_type_map' map.
132 Represents (pon_intf_id, onu_id, uni_id) */
133typedef std::tuple<uint32_t, uint32_t, uint32_t> qos_type_map_key_tuple;
134/* 'qos_type_map' maps qos_type_map_key_tuple to qos_type*/
135static std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type> qos_type_map;
136
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000137/* This represents the Key to 'sched_qmp_id_map' map.
138Represents (sched_id, pon_intf_id, onu_id, uni_id) */
139typedef std::tuple<uint32_t, uint32_t, uint32_t, uint32_t> sched_qmp_id_map_key_tuple;
140/* 'sched_qmp_id_map' maps sched_qmp_id_map_key_tuple to TM Queue Mapping Profile ID */
141static std::map<sched_qmp_id_map_key_tuple, int> sched_qmp_id_map;
142/* 'qmp_id_to_qmp_map' maps TM Queue Mapping Profile ID to TM Queue Mapping Profile */
143static std::map<int, std::vector < uint32_t > > qmp_id_to_qmp_map;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800144
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800145std::bitset<MAX_TM_SCHED_ID> tm_sched_bitset;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000146std::bitset<MAX_TM_QMP_ID> tm_qmp_bitset;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800147
148static bcmos_fastlock data_lock;
Craig Lutgen967a1d02018-11-27 10:41:51 -0600149
150#define MIN_ALLOC_ID_GPON 256
151#define MIN_ALLOC_ID_XGSPON 1024
152
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800153static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
154 uint32_t port_no, uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, \
155 uint32_t priority, tech_profile::SchedulingPolicy sched_policy,
156 tech_profile::TrafficShapingInfo traffic_shaping_info);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000157static 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 -0800158static 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 -0500159 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
160static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
161 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000162static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
163static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
164
165uint16_t get_dev_id(void) {
166 return dev_id;
167}
Shad Ansari627b5782018-08-13 22:49:32 +0000168
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400169// Stubbed defntions of bcmolt_cfg_get required for unit-test
170#ifdef TEST_MODE
171extern bcmos_errno bcmolt_cfg_get__bal_state_stub(bcmolt_oltid olt_id, void* ptr);
172extern bcmos_errno bcmolt_cfg_get__olt_topology_stub(bcmolt_oltid olt_id, void* ptr);
173#endif
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800174/**
175* Returns the default NNI (Upstream direction) or PON (Downstream direction) scheduler
176* Every NNI port and PON port have default scheduler.
177* The NNI0 default scheduler ID is 18432, and NNI1 is 18433 and so on.
178* Similarly, PON0 default scheduler ID is 16384. PON1 is 16385 and so on.
179*
180* @param intf_id NNI or PON interface ID
181* @param direction "upstream" or "downstream"
182*
183* @return default scheduler ID for the given interface.
184*/
185static inline int get_default_tm_sched_id(int intf_id, std::string direction) {
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700186 if (direction.compare(upstream) == 0) {
187 return tm_upstream_sched_id_start + intf_id;
188 } else if (direction.compare(downstream) == 0) {
189 return tm_downstream_sched_id_start + intf_id;
190 }
191 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000192 OPENOLT_LOG(ERROR, openolt_log_id, "invalid direction - %s\n", direction.c_str());
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700193 return 0;
194 }
195}
196
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800197/**
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800198* Gets a unique tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
199* The tm_sched_id is locally cached in a map, so that it can rendered when necessary.
200* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
201*
202* @param intf_id NNI or PON intf ID
203* @param onu_id ONU ID
204* @param uni_id UNI ID
205* @param gemport_id GEM Port ID
206* @param direction Upstream or downstream
207*
208* @return tm_sched_id
209*/
210uint32_t get_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
211 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
212 int sched_id = -1;
213
214 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
215 if (it != sched_map.end()) {
216 sched_id = it->second;
217 }
218 if (sched_id != -1) {
219 return sched_id;
220 }
221
222 bcmos_fastlock_lock(&data_lock);
223 // Complexity of O(n). Is there better way that can avoid linear search?
224 for (sched_id = 0; sched_id < MAX_TM_SCHED_ID; sched_id++) {
225 if (tm_sched_bitset[sched_id] == 0) {
226 tm_sched_bitset[sched_id] = 1;
227 break;
228 }
229 }
230 bcmos_fastlock_unlock(&data_lock, 0);
231
232 if (sched_id < MAX_TM_SCHED_ID) {
233 bcmos_fastlock_lock(&data_lock);
234 sched_map[key] = sched_id;
235 bcmos_fastlock_unlock(&data_lock, 0);
236 return sched_id;
237 } else {
238 return -1;
239 }
240}
241
242/**
243* Free tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
244*
245* @param intf_id NNI or PON intf ID
246* @param onu_id ONU ID
247* @param uni_id UNI ID
248* @param gemport_id GEM Port ID
249* @param direction Upstream or downstream
250*/
251void free_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
252 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
253 std::map<sched_map_key_tuple, int>::const_iterator it;
254 bcmos_fastlock_lock(&data_lock);
255 it = sched_map.find(key);
256 if (it != sched_map.end()) {
257 tm_sched_bitset[it->second] = 0;
258 sched_map.erase(it);
259 }
260 bcmos_fastlock_unlock(&data_lock, 0);
261}
262
263bool is_tm_sched_id_present(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
264 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000265 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
266 if (it != sched_map.end()) {
267 return true;
268 }
269 return false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800270}
271
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000272/**
273* Check whether given two tm qmp profiles are equal or not
274*
275* @param tmq_map_profileA <vector> TM QUEUE MAPPING PROFILE
276* @param tmq_map_profileB <vector> TM QUEUE MAPPING PROFILE
277*
278* @return boolean, true if given tmq_map_profiles are equal else false
279*/
280
281bool check_tm_qmp_equality(std::vector<uint32_t> tmq_map_profileA, std::vector<uint32_t> tmq_map_profileB) {
282 for (uint32_t i = 0; i < TMQ_MAP_PROFILE_SIZE; i++) {
283 if (tmq_map_profileA[i] != tmq_map_profileB[i]) {
284 return false;
285 }
286 }
287 return true;
Shad Ansari627b5782018-08-13 22:49:32 +0000288}
289
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000290/**
291* Modifies given queues_pbit_map to parsable format
292* e.g: Modifes "0b00000101" to "10100000"
293*
294* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
295* @param size Queue count
296*
297* @return string queues_pbit_map
298*/
299std::string* get_valid_queues_pbit_map(std::string *queues_pbit_map, uint32_t size) {
300 for(uint32_t i=0; i < size; i++) {
301 /* Deletes 2 characters from index number 0 */
302 queues_pbit_map[i].erase(0, 2);
303 std::reverse(queues_pbit_map[i].begin(), queues_pbit_map[i].end());
304 }
305 return queues_pbit_map;
306}
307
308/**
309* Creates TM QUEUE MAPPING PROFILE for given queues_pbit_map and queues_priority_q
310*
311* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
312* @param queues_priority_q PRIORITY_Q configured for each GEM in TECH PROFILE
313* @param size Queue count
314*
315* @return <vector> TM QUEUE MAPPING PROFILE
316*/
317std::vector<uint32_t> get_tmq_map_profile(std::string *queues_pbit_map, uint32_t *queues_priority_q, uint32_t size) {
318 std::vector<uint32_t> tmq_map_profile(8,0);
319
320 for(uint32_t i=0; i < size; i++) {
321 for (uint32_t j = 0; j < queues_pbit_map[i].size(); j++) {
322 if (queues_pbit_map[i][j]=='1') {
323 tmq_map_profile.at(j) = queue_id_list[queues_priority_q[i]];
324 }
325 }
326 }
327 return tmq_map_profile;
328}
329
330/**
331* Gets corresponding tm_qmp_id for a given tmq_map_profile
332*
333* @param <vector> TM QUEUE MAPPING PROFILE
334*
335* @return tm_qmp_id
336*/
337int get_tm_qmp_id(std::vector<uint32_t> tmq_map_profile) {
338 int tm_qmp_id = -1;
339
340 std::map<int, std::vector < uint32_t > >::const_iterator it = qmp_id_to_qmp_map.begin();
341 while(it != qmp_id_to_qmp_map.end()) {
342 if(check_tm_qmp_equality(tmq_map_profile, it->second)) {
343 tm_qmp_id = it->first;
344 break;
345 }
346 it++;
347 }
348 return tm_qmp_id;
349}
350
351/**
352* Updates sched_qmp_id_map with given sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id
353*
354* @param upstream/downstream sched_id
355* @param PON intf ID
356* @param onu_id ONU ID
357* @param uni_id UNI ID
358* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
359*/
360void update_sched_qmp_id_map(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
361 uint32_t uni_id, int tm_qmp_id) {
362 bcmos_fastlock_lock(&data_lock);
363 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
364 sched_qmp_id_map.insert(make_pair(key, tm_qmp_id));
365 bcmos_fastlock_unlock(&data_lock, 0);
366}
367
368/**
369* Gets corresponding tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
370*
371* @param upstream/downstream sched_id
372* @param PON intf ID
373* @param onu_id ONU ID
374* @param uni_id UNI ID
375*
376* @return tm_qmp_id
377*/
378int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
379 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
380 int tm_qmp_id = -1;
381
382 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
383 if (it != sched_qmp_id_map.end()) {
384 tm_qmp_id = it->second;
385 }
386 return tm_qmp_id;
387}
388
389/**
390* Gets a unique tm_qmp_id for a given tmq_map_profile
391* The tm_qmp_id is locally cached in a map, so that it can be rendered when necessary.
392* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
393*
394* @param upstream/downstream sched_id
395* @param PON intf ID
396* @param onu_id ONU ID
397* @param uni_id UNI ID
398* @param <vector> TM QUEUE MAPPING PROFILE
399*
400* @return tm_qmp_id
401*/
402int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, \
403 std::vector<uint32_t> tmq_map_profile) {
404 int tm_qmp_id;
405
406 bcmos_fastlock_lock(&data_lock);
407 /* Complexity of O(n). Is there better way that can avoid linear search? */
408 for (tm_qmp_id = 0; tm_qmp_id < MAX_TM_QMP_ID; tm_qmp_id++) {
409 if (tm_qmp_bitset[tm_qmp_id] == 0) {
410 tm_qmp_bitset[tm_qmp_id] = 1;
411 break;
412 }
413 }
414 bcmos_fastlock_unlock(&data_lock, 0);
415
416 if (tm_qmp_id < MAX_TM_QMP_ID) {
417 bcmos_fastlock_lock(&data_lock);
418 qmp_id_to_qmp_map.insert(make_pair(tm_qmp_id, tmq_map_profile));
419 bcmos_fastlock_unlock(&data_lock, 0);
420 update_sched_qmp_id_map(sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id);
421 return tm_qmp_id;
422 } else {
423 return -1;
424 }
425}
426
427/**
428* Free tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
429*
430* @param upstream/downstream sched_id
431* @param PON intf ID
432* @param onu_id ONU ID
433* @param uni_id UNI ID
434* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
435*
436* @return boolean, true if no more reference for TM QMP else false
437*/
438bool free_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
439 uint32_t uni_id, int tm_qmp_id) {
440 bool result;
441 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
442 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
443 bcmos_fastlock_lock(&data_lock);
444 if (it != sched_qmp_id_map.end()) {
445 sched_qmp_id_map.erase(it);
446 }
447 bcmos_fastlock_unlock(&data_lock, 0);
448
449 uint32_t tm_qmp_ref_count = 0;
450 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it2 = sched_qmp_id_map.begin();
451 while(it2 != sched_qmp_id_map.end()) {
452 if(it2->second == tm_qmp_id) {
453 tm_qmp_ref_count++;
454 }
455 it2++;
456 }
457
458 if (tm_qmp_ref_count == 0) {
459 std::map<int, std::vector < uint32_t > >::const_iterator it3 = qmp_id_to_qmp_map.find(tm_qmp_id);
460 if (it3 != qmp_id_to_qmp_map.end()) {
461 bcmos_fastlock_lock(&data_lock);
462 tm_qmp_bitset[tm_qmp_id] = 0;
463 qmp_id_to_qmp_map.erase(it3);
464 bcmos_fastlock_unlock(&data_lock, 0);
465 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So clearing it\n", \
466 tm_qmp_id, tm_qmp_ref_count);
467 result = true;
468 }
469 } else {
470 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So not clearing it\n", \
471 tm_qmp_id, tm_qmp_ref_count);
472 result = false;
473 }
474 return result;
475}
476
477/**
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -0500478* Returns qos type as string
479*
480* @param qos_type bcmolt_egress_qos_type enum
481*/
482std::string get_qos_type_as_string(bcmolt_egress_qos_type qos_type) {
483 switch (qos_type)
484 {
485 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE: return "FIXED_QUEUE";
486 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE: return "TC_TO_QUEUE";
487 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC: return "PBIT_TO_TC";
488 case BCMOLT_EGRESS_QOS_TYPE_NONE: return "NONE";
489 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE: return "PRIORITY_TO_QUEUE";
490 default: OPENOLT_LOG(ERROR, openolt_log_id, "qos-type-not-supported %d\n", qos_type);
491 return "qos-type-not-supported";
492 }
493}
494
495/**
496* Gets/Updates qos type for given pon_intf_id, onu_id, uni_id
497*
498* @param PON intf ID
499* @param onu_id ONU ID
500* @param uni_id UNI ID
501* @param queue_size TrafficQueues Size
502*
503* @return qos_type
504*/
505bcmolt_egress_qos_type get_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t queue_size = 0) {
506 qos_type_map_key_tuple key(pon_intf_id, onu_id, uni_id);
507 bcmolt_egress_qos_type egress_qos_type = BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
508 std::string qos_string;
509
510 std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type>::const_iterator it = qos_type_map.find(key);
511 if (it != qos_type_map.end()) {
512 egress_qos_type = it->second;
513 qos_string = get_qos_type_as_string(egress_qos_type);
514 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", \
515 pon_intf_id, onu_id, uni_id, qos_string.c_str());
516 }
517 else {
518 /* QOS Type has been pre-defined as Fixed Queue but it will be updated based on number of GEMPORTS
519 associated for a given subscriber. If GEM count = 1 for a given subscriber, qos_type will be Fixed Queue
520 else Priority to Queue */
521 egress_qos_type = (queue_size > 1) ? \
522 BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE : BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
523 bcmos_fastlock_lock(&data_lock);
524 qos_type_map.insert(make_pair(key, egress_qos_type));
525 bcmos_fastlock_unlock(&data_lock, 0);
526 qos_string = get_qos_type_as_string(egress_qos_type);
527 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", \
528 pon_intf_id, onu_id, uni_id, qos_string.c_str());
529 }
530 return egress_qos_type;
531}
532
533/**
534* Clears qos type for given pon_intf_id, onu_id, uni_id
535*
536* @param PON intf ID
537* @param onu_id ONU ID
538* @param uni_id UNI ID
539*/
540void clear_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
541 qos_type_map_key_tuple key(pon_intf_id, onu_id, uni_id);
542 std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type>::const_iterator it = qos_type_map.find(key);
543 bcmos_fastlock_lock(&data_lock);
544 if (it != qos_type_map.end()) {
545 qos_type_map.erase(it);
546 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", \
547 pon_intf_id, onu_id, uni_id);
548 }
549 bcmos_fastlock_unlock(&data_lock, 0);
550}
551
552/**
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000553* Returns Scheduler/Queue direction as string
554*
555* @param direction as specified in tech_profile.proto
556*/
557std::string GetDirection(int direction) {
558 switch (direction)
559 {
560 case tech_profile::Direction::UPSTREAM: return upstream;
561 case tech_profile::Direction::DOWNSTREAM: return downstream;
562 default: OPENOLT_LOG(ERROR, openolt_log_id, "direction-not-supported %d\n", direction);
563 return "direction-not-supported";
564 }
565}
566
567inline const char *get_flow_acton_command(uint32_t command) {
568 char actions[200] = { };
569 char *s_actions_ptr = actions;
570 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
571 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
572 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
573 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
574 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
575 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
576 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
577 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
578 return s_actions_ptr;
579}
580
581char* openolt_read_sysinfo(const char* field_name, char* field_val)
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800582{
583 FILE *fp;
584 /* Prepare the command*/
585 char command[150];
586
587 snprintf(command, sizeof command, "bash -l -c \"onlpdump -s\" | perl -ne 'print $1 if /%s: (\\S+)/'", field_name);
588 /* Open the command for reading. */
589 fp = popen(command, "r");
590 if (fp == NULL) {
591 /*The client has to check for a Null field value in this case*/
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000592 OPENOLT_LOG(INFO, openolt_log_id, "Failed to query the %s\n", field_name);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800593 return field_val;
594 }
595
596 /*Read the field value*/
597 if (fp) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000598 uint8_t ret;
599 ret = fread(field_val, OPENOLT_FIELD_LEN, 1, fp);
600 if (ret >= OPENOLT_FIELD_LEN)
601 OPENOLT_LOG(INFO, openolt_log_id, "Read data length %u\n", ret);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800602 pclose(fp);
603 }
604 return field_val;
605}
606
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400607Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500608 device_info->set_vendor(VENDOR_ID);
609 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400610 device_info->set_hardware_version("");
611 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500612 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500613 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500614
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800615 char serial_number[OPENOLT_FIELD_LEN];
616 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
617 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000618 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800619 device_info->set_device_serial_number(serial_number);
620
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700621 char device_id[OPENOLT_FIELD_LEN];
622 memset(device_id, '\0', OPENOLT_FIELD_LEN);
623 openolt_read_sysinfo("MAC", device_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000624 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700625 device_info->set_device_id(device_id);
626
Craig Lutgenb2601f02018-10-23 13:04:31 -0500627 // Legacy, device-wide ranges. To be deprecated when adapter
628 // is upgraded to support per-interface ranges
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000629 if (board_technology == "XGS-PON") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500630 device_info->set_onu_id_start(1);
631 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600632 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500633 device_info->set_alloc_id_end(16383);
634 device_info->set_gemport_id_start(1024);
635 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500636 device_info->set_flow_id_start(1);
637 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500638 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000639 else if (board_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500640 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500641 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600642 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500643 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500644 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500645 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500646 device_info->set_flow_id_start(1);
647 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500648 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500649
650 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
651 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
652 std::string intf_technology = intf_technologies[intf_id];
653 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
654 if(range == nullptr) {
655 range = device_info->add_ranges();
656 ranges[intf_technology] = range;
657 range->set_technology(intf_technology);
658
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000659 if (intf_technology == "XGS-PON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500660 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
661
662 pool = range->add_pools();
663 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
664 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
665 pool->set_start(1);
666 pool->set_end(255);
667
668 pool = range->add_pools();
669 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
670 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
671 pool->set_start(1024);
672 pool->set_end(16383);
673
674 pool = range->add_pools();
675 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
676 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
677 pool->set_start(1024);
678 pool->set_end(65535);
679
680 pool = range->add_pools();
681 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
682 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
683 pool->set_start(1);
684 pool->set_end(16383);
685 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000686 else if (intf_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500687 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
688
689 pool = range->add_pools();
690 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
691 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
692 pool->set_start(1);
693 pool->set_end(127);
694
695 pool = range->add_pools();
696 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
697 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
698 pool->set_start(256);
699 pool->set_end(757);
700
701 pool = range->add_pools();
702 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
703 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
704 pool->set_start(256);
705 pool->set_end(4095);
706
707 pool = range->add_pools();
708 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
709 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
710 pool->set_start(1);
711 pool->set_end(16383);
712 }
713 }
714
715 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500716 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400717
718 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500719 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400720 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
721 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500722 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400723 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500724 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
725 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400726
727 return Status::OK;
728}
729
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000730Status pushOltOperInd(uint32_t intf_id, const char *type, const char *state)
731{
732 openolt::Indication ind;
733 openolt::IntfOperIndication* intf_oper_ind = new openolt::IntfOperIndication;
734
735 intf_oper_ind->set_type(type);
736 intf_oper_ind->set_intf_id(intf_id);
737 intf_oper_ind->set_oper_state(state);
738 ind.set_allocated_intf_oper_ind(intf_oper_ind);
739 oltIndQ.push(ind);
740 return Status::OK;
741}
742
743#define CLI_HOST_PROMPT_FORMAT "BCM.%u> "
744
745/* Build CLI prompt */
746static void openolt_cli_get_prompt_cb(bcmcli_session *session, char *buf, uint32_t max_len)
747{
748 snprintf(buf, max_len, CLI_HOST_PROMPT_FORMAT, dev_id);
749}
750
751static int _bal_apiend_cli_thread_handler(long data)
752{
753 char init_string[]="\n";
754 bcmcli_session *sess = current_session;
755 bcmos_task_parm bal_cli_task_p_dummy;
756
757 /* Switch to interactive mode if not stopped in the init script */
758 if (!bcmcli_is_stopped(sess))
759 {
760 /* Force a CLI command prompt
761 * The string passed into the parse function
762 * must be modifiable, so a string constant like
763 * bcmcli_parse(current_session, "\n") will not
764 * work.
765 */
766 bcmcli_parse(sess, init_string);
767
768 /* Process user input until EOF or quit command */
769 bcmcli_driver(sess);
770 };
771 OPENOLT_LOG(INFO, openolt_log_id, "BAL API End CLI terminated\n");
772
773 /* Cleanup */
774 bcmcli_session_close(current_session);
775 bcmcli_token_destroy(NULL);
776 return 0;
777}
778
779/* Init API CLI commands for the current device */
780bcmos_errno bcm_openolt_api_cli_init(bcmcli_entry *parent_dir, bcmcli_session *session)
781{
782 bcmos_errno rc;
783
784 api_parent_dir = parent_dir;
785
786 rc = bcm_api_cli_set_commands(session);
787
788#ifdef BCM_SUBSYSTEM_HOST
789 /* Subscribe for device change indication */
790 rc = rc ? rc : bcmolt_olt_sel_ind_register(_api_cli_olt_change_ind);
791#endif
792
793 return rc;
794}
795
796static bcmos_errno bcm_cli_quit(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
797{
798 bcmcli_stop(session);
799 bcmcli_session_print(session, "CLI terminated by 'Quit' command\n");
800 status_bcm_cli_quit = BCMOS_TRUE;
801
802 return BCM_ERR_OK;
803}
804
805int get_status_bcm_cli_quit(void) {
806 return status_bcm_cli_quit;
807}
808
809bcmos_errno bcmolt_apiend_cli_init() {
810 bcmos_errno ret;
811 bcmos_task_parm bal_cli_task_p = {};
812 bcmos_task_parm bal_cli_task_p_dummy;
813
814 /** before creating the task, check if it is already created by the other half of BAL i.e. Core side */
815 if (BCM_ERR_OK != bcmos_task_query(&bal_cli_thread, &bal_cli_task_p_dummy))
816 {
817 /* Create BAL CLI thread */
818 bal_cli_task_p.name = bal_cli_thread_name;
819 bal_cli_task_p.handler = _bal_apiend_cli_thread_handler;
820 bal_cli_task_p.priority = TASK_PRIORITY_CLI;
821
822 ret = bcmos_task_create(&bal_cli_thread, &bal_cli_task_p);
823 if (BCM_ERR_OK != ret)
824 {
825 bcmos_printf("Couldn't create BAL API end CLI thread\n");
826 return ret;
827 }
828 }
829}
830
Shad Ansari627b5782018-08-13 22:49:32 +0000831Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000832 bcmos_errno err;
833 bcmolt_host_init_parms init_parms = {};
834 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
835 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000836
Shad Ansariedef2132018-08-10 22:14:50 +0000837 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000838
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500839 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000840 /* Initialize host subsystem */
841 err = bcmolt_host_init(&init_parms);
842 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500843 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000844 return bcm_to_grpc_err(err, "Failed to init OLT");
845 }
846
847 bcmcli_session_parm mon_session_parm;
848 /* Create CLI session */
849 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
850 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
851 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
852 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
853 BUG_ON(rc != BCM_ERR_OK);
854
855 /* API CLI */
856 bcm_openolt_api_cli_init(NULL, current_session);
857
858 /* Add quit command */
859 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
860
861 err = bcmolt_apiend_cli_init();
862 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500863 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000864 return bcm_to_grpc_err(err, "Failed to add apiend init");
865 }
866
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800867 bcmos_fastlock_init(&data_lock, 0);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000868 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600869
Jason Huangbf45ffb2019-10-30 17:29:02 +0800870 //check BCM daemon is connected or not
871 Status status = check_connection();
872 if (!status.ok())
873 return status;
874 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000875 Status status = SubscribeIndication();
876 if (!status.ok()) {
877 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
878 grpc_status_code_to_string(status.error_code()).c_str(),
879 status.error_message().c_str());
880 return status;
881 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800882
883 //check BAL state in initial stage
884 status = check_bal_ready();
885 if (!status.ok())
886 return status;
887 }
888
889 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000890 bcmos_errno err;
891 bcmolt_odid dev;
892 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
893 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400894 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000895 bcmolt_device_key dev_key = { };
896 dev_key.device_id = dev;
897 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
898 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
899 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800900 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000901 bcmolt_device_key key = {.device_id = dev};
902 bcmolt_device_connect oper;
903 BCMOLT_OPER_INIT(&oper, device, connect, key);
904 if (MODEL_ID == "asfvolt16") {
905 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
906 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
907 } else if (MODEL_ID == "asgvolt64") {
908 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
909 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
910 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
911 }
912 err = bcmolt_oper_submit(dev_id, &oper.hdr);
913 if (err) {
914 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500915 OPENOLT_LOG(ERROR, openolt_log_id, "Enable PON device %d failed, err = %s\n", dev, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000916 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500917 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable all the pon ports, err = %s\n", bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000918 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
919 }
920 }
921 bcmos_usleep(200000);
922 }
923 else {
924 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
925 state.activate();
926 }
927 }
928 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000929 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000930 }
Shad Ansariedef2132018-08-10 22:14:50 +0000931
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000932 /* Start CLI */
933 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400934 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000935 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400936}
937
938Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400939 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
940 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
941 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
942 //To overcome this disable is implemented by disabling all the PON ports
943 //associated with the device so as to support both in-band
944 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400945
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400946 Status status;
947 int failedCount = 0;
948 for (int i = 0; i < NumPonIf_(); i++) {
949 status = DisablePonIf_(i);
950 if (!status.ok()) {
951 failedCount+=1;
952 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
953 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400954 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400955 if (failedCount == 0) {
956 state.deactivate();
957 openolt::Indication ind;
958 openolt::OltIndication* olt_ind = new openolt::OltIndication;
959 olt_ind->set_oper_state("down");
960 ind.set_allocated_olt_ind(olt_ind);
961 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
962 oltIndQ.push(ind);
963 return Status::OK;
964 }
965 if (failedCount ==NumPonIf_()){
966 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
967 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400968
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400969 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 -0400970}
971
972Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400973 Status status;
974 int failedCount = 0;
975 for (int i = 0; i < NumPonIf_(); i++) {
976 status = EnablePonIf_(i);
977 if (!status.ok()) {
978 failedCount+=1;
979 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
980 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400981 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400982 if (failedCount == 0){
983 state.activate();
984 openolt::Indication ind;
985 openolt::OltIndication* olt_ind = new openolt::OltIndication;
986 olt_ind->set_oper_state("up");
987 ind.set_allocated_olt_ind(olt_ind);
988 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
989 oltIndQ.push(ind);
990 return Status::OK;
991 }
992 if (failedCount ==NumPonIf_()){
993 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
994 }
995 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 +0000996}
997
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000998bcmos_errno get_pon_interface_status(bcmolt_interface pon_ni, bcmolt_interface_state *state) {
999 bcmos_errno err;
1000 bcmolt_pon_interface_key pon_key;
1001 bcmolt_pon_interface_cfg pon_cfg;
1002 pon_key.pon_ni = pon_ni;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001003
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001004 BCMOLT_CFG_INIT(&pon_cfg, pon_interface, pon_key);
1005 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, state);
1006 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, itu);
1007 err = bcmolt_cfg_get(dev_id, &pon_cfg.hdr);
1008 *state = pon_cfg.data.state;
1009 return err;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001010}
1011
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001012inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
1013 bcmos_errno err;
1014 bcmolt_flow_key flow_key;
1015 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001016
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001017 flow_key.flow_id = flow_id;
1018 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001019
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001020 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001021
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001022 switch (data_id) {
1023 case ONU_ID: //onu_id
1024 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
1025 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1026 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001027 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001028 return err;
1029 }
1030 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001031 case FLOW_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001032 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1033 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001034 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001035 return err;
1036 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001037 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001038 case SVC_PORT_ID: //svc_port_id
1039 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
1040 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1041 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001042 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get svc_port_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001043 return err;
1044 }
1045 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001046 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001047 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
1048 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1049 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001050 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001051 return err;
1052 }
1053 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001054 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001055 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
1056 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1057 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001058 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001059 return err;
1060 }
1061 return flow_cfg.data.cookie;
1062 case INGRESS_INTF_TYPE: //ingress intf_type
1063 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
1064 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1065 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001066 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001067 return err;
1068 }
1069 return flow_cfg.data.ingress_intf.intf_type;
1070 case EGRESS_INTF_TYPE: //egress intf_type
1071 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
1072 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1073 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001074 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001075 return err;
1076 }
1077 return flow_cfg.data.egress_intf.intf_type;
1078 case INGRESS_INTF_ID: //ingress intf_id
1079 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
1080 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1081 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001082 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001083 return err;
1084 }
1085 return flow_cfg.data.ingress_intf.intf_id;
1086 case EGRESS_INTF_ID: //egress intf_id
1087 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
1088 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1089 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001090 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001091 return err;
1092 }
1093 return flow_cfg.data.egress_intf.intf_id;
1094 case CLASSIFIER_O_VID:
1095 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1096 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1097 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001098 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001099 return err;
1100 }
1101 return flow_cfg.data.classifier.o_vid;
1102 case CLASSIFIER_O_PBITS:
1103 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1104 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1105 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001106 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001107 return err;
1108 }
1109 return flow_cfg.data.classifier.o_pbits;
1110 case CLASSIFIER_I_VID:
1111 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1112 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1113 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001114 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001115 return err;
1116 }
1117 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001118 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001119 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1120 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1121 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001122 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001123 return err;
1124 }
1125 return flow_cfg.data.classifier.i_pbits;
1126 case CLASSIFIER_ETHER_TYPE:
1127 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1128 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1129 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001130 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ether_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001131 return err;
1132 }
1133 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001134 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001135 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1136 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1137 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001138 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ip_proto, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001139 return err;
1140 }
1141 return flow_cfg.data.classifier.ip_proto;
1142 case CLASSIFIER_SRC_PORT:
1143 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1144 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1145 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001146 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier src_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001147 return err;
1148 }
1149 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001150 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001151 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1152 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1153 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001154 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier dst_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001155 return err;
1156 }
1157 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001158 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001159 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1160 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1161 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001162 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier pkt_tag_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001163 return err;
1164 }
1165 return flow_cfg.data.classifier.pkt_tag_type;
1166 case EGRESS_QOS_TYPE:
1167 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1168 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1169 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001170 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001171 return err;
1172 }
1173 return flow_cfg.data.egress_qos.type;
1174 case EGRESS_QOS_QUEUE_ID:
1175 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1176 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1177 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001178 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos queue_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001179 return err;
1180 }
1181 switch (flow_cfg.data.egress_qos.type) {
1182 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
1183 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
1184 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
1185 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
1186 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
1187 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
1188 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
1189 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
1190 case BCMOLT_EGRESS_QOS_TYPE_NONE:
1191 default:
1192 return -1;
1193 }
1194 case EGRESS_QOS_TM_SCHED_ID:
1195 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1196 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1197 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001198 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos tm_sched_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001199 return err;
1200 }
1201 return flow_cfg.data.egress_qos.tm_sched.id;
1202 case ACTION_CMDS_BITMASK:
1203 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1204 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1205 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001206 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action cmds_bitmask, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001207 return err;
1208 }
1209 return flow_cfg.data.action.cmds_bitmask;
1210 case ACTION_O_VID:
1211 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1212 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1213 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001214 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001215 return err;
1216 }
1217 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001218 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001219 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1220 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1221 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001222 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001223 return err;
1224 }
1225 return flow_cfg.data.action.o_pbits;
1226 case ACTION_I_VID:
1227 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1228 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1229 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001230 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001231 return err;
1232 }
1233 return flow_cfg.data.action.i_vid;
1234 case ACTION_I_PBITS:
1235 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1236 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1237 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001238 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001239 return err;
1240 }
1241 return flow_cfg.data.action.i_pbits;
1242 case STATE:
1243 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
1244 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1245 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001246 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001247 return err;
1248 }
1249 return flow_cfg.data.state;
1250 default:
1251 return BCM_ERR_INTERNAL;
1252 }
1253
1254 return err;
1255}
1256
1257Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001258 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001259 bcmolt_pon_interface_cfg interface_obj;
1260 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1261 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
1262 bcmolt_interface_state state;
1263
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001264 err = get_pon_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001265 if (err == BCM_ERR_OK) {
1266 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001267 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001268 return Status::OK;
1269 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001270 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001271 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1272 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1273 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
1274 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
1275 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
1276 BCMOLT_ONU_POST_DISCOVERY_MODE_ACTIVATE);
1277 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
1278 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
1279 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
1280 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
1281 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
1282 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
1283 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1284 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1285
1286 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1287 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001288 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable discovery onu, PON interface %d, err = %s\n", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001289 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
1290 }
1291 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1292 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001293 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d, err = %s\n", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001294 return bcm_to_grpc_err(err, "Failed to enable PON interface");
1295 }
1296 else {
1297 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
1298 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
1299 CreateDefaultSched(intf_id, downstream);
1300 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001301 }
1302
1303 return Status::OK;
1304}
1305
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001306/* Same as bcmolt_cfg_get but with added logic of retrying the API
1307 in case of some specific failures like timeout or object not yet ready
1308*/
1309bcmos_errno bcmolt_cfg_get_mult_retry(bcmolt_oltid olt, bcmolt_cfg *cfg) {
1310 bcmos_errno err;
1311 uint32_t current_try = 0;
1312
1313 while (current_try < MAX_BAL_API_RETRY_COUNT) {
1314 err = bcmolt_cfg_get(olt, cfg);
1315 current_try++;
1316
1317 if (err == BCM_ERR_STATE || err == BCM_ERR_TIMEOUT) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001318 OPENOLT_LOG(WARNING, openolt_log_id, "bcmolt_cfg_get: err = %s\n", bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001319 bcmos_usleep(BAL_API_RETRY_TIME_IN_USECS);
1320 continue;
1321 }
1322 else {
1323 break;
1324 }
1325 }
1326
1327 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001328 OPENOLT_LOG(ERROR, openolt_log_id, "bcmolt_cfg_get tried (%d) times with retry time(%d usecs) err = %s\n",
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001329 current_try,
1330 BAL_API_RETRY_TIME_IN_USECS,
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001331 bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001332 }
1333 return err;
1334}
1335
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001336Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001337 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001338 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001339 bcmolt_device_key dev_key = { };
1340 bcmolt_olt_cfg olt_cfg = { };
1341 bcmolt_olt_key olt_key = { };
1342 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
1343 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001344
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001345 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
1346 topo.topology_maps.arr = &topo_map[0];
1347 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
1348 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
1349 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001350 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001351 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001352 #ifdef TEST_MODE
1353 // It is impossible to mock the setting of olt_cfg.data.bal_state because
1354 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
1355 // set the olt_cfg.data.topology. So a new stub function is created and address
1356 // of olt_cfg is passed. This is one-of case where we need to test add specific
1357 // code in production code.
1358 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
1359 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001360 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001361 #endif
1362 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001363 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query OLT topology, err = %s\n", bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001364 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001365 }
1366
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001367 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
1368 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001369
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001370 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
1371 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001372 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001373
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001374 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
1375 num_of_nni_ports,
1376 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001377 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001378
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001379 uint32_t num_failed_cfg_gets = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001380 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1381 dev_key.device_id = devid;
1382 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1383 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1384 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1385 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001386 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001387 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001388 OPENOLT_LOG(WARNING, openolt_log_id,"Failed to query PON MAC Device %d (errno = %s). Skipping the device.\n", devid, bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001389 num_failed_cfg_gets++;
1390 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001391 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001392
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001393 std::string bal_version;
1394 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1395 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1396 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
1397 firmware_version = "BAL." + bal_version + "__" + firmware_version;
1398
1399 switch(dev_cfg.data.system_mode) {
1400 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1401 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1402 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1403 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1404 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1405 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1406 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1407 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1408 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1409 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1410 }
1411
1412 switch(dev_cfg.data.chip_family) {
1413 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X_: chip_family = "Maple"; break;
1414 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X_: chip_family = "Aspen"; break;
1415 }
1416
1417 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s object model: %d, family: %s, board_technology: %s\n",
1418 devid, BCM_MAX_PONS_PER_DEV, bal_version.c_str(), BAL_API_VERSION, chip_family.c_str(), board_technology.c_str());
1419
1420 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001421 }
1422
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001423 /* If all the devices returned errors then we tell the caller that this is an error else we work with
1424 only the devices that retured success*/
1425 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1426 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1427 return bcm_to_grpc_err(err, "device: All devices failed query");
1428 }
1429
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001430 return Status::OK;
1431}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001432#if 0
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001433Status ProbePonIfTechnology_() {
1434 // Probe maximum extent possible as configured into BAL driver to determine
1435 // which are active in the current BAL topology. And for those
1436 // that are active, determine each port's access technology, i.e. "gpon" or "xgspon".
1437 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001438 bcmolt_pon_interface_cfg interface_obj;
1439 bcmolt_pon_interface_key interface_key;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001440
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001441 interface_key.pon_ni = intf_id;
1442 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001443 if (board_technology == "XGS-PON"
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001444 BCMOLT_MSG_FIELD_GET(&interface_obj, xgs_ngpon2_trx);
1445 else if (board_technology == "GPON")
1446 BCMOLT_MSG_FIELD_GET(&interface_obj, gpon_trx);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001447
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001448 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001449 if (err != BCM_ERR_OK) {
Craig Lutgenb2601f02018-10-23 13:04:31 -05001450 intf_technologies[intf_id] = UNKNOWN_TECH;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001451 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 -05001452 }
1453 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001454 if (board_technology == "XGS-PON") {
1455 switch(interface_obj.data.xgpon_trx.transceiver_type) {
1456 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_PC:
1457 case BCMOLT_XGPON_TRX_TYPE_WTD_RTXM266_702:
1458 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_BC_PLUS:
1459 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_PC:
1460 case BCMOLT_XGPON_TRX_TYPE_LTH_5302_PC:
1461 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_A_PC_PLUS:
1462 case BCMOLT_XGPON_TRX_TYPE_D272RR_SSCB_DM:
1463 intf_technologies[intf_id] = "XGS-PON";
1464 break;
1465 }
1466 } else if (board_technology == "GPON") {
1467 switch(interface_obj.data.gpon_trx.transceiver_type) {
1468 case BCMOLT_TRX_TYPE_SPS_43_48_H_HP_CDE_SD_2013:
1469 case BCMOLT_TRX_TYPE_LTE_3680_M:
1470 case BCMOLT_TRX_TYPE_SOURCE_PHOTONICS:
1471 case BCMOLT_TRX_TYPE_LTE_3680_P_TYPE_C_PLUS:
1472 case BCMOLT_TRX_TYPE_LTE_3680_P_BC:
1473 intf_technologies[intf_id] = "GPON";
1474 break;
1475 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001476 }
Craig Lutgenb2601f02018-10-23 13:04:31 -05001477
1478 if (board_technology != UNKNOWN_TECH) {
1479 board_technology = intf_technologies[intf_id];
1480 } else if (board_technology != MIXED_TECH && board_technology != intf_technologies[intf_id]) {
1481 intf_technologies[intf_id] = MIXED_TECH;
1482 }
1483
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001484 }
1485 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001486 return Status::OK;
1487}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001488#endif
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001489unsigned NumNniIf_() {return num_of_nni_ports;}
1490unsigned NumPonIf_() {return num_of_pon_ports;}
1491
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001492bcmos_errno get_nni_interface_status(bcmolt_interface id, bcmolt_interface_state *state) {
1493 bcmos_errno err;
1494 bcmolt_nni_interface_key nni_key;
1495 bcmolt_nni_interface_cfg nni_cfg;
1496 nni_key.id = id;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001497
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001498 BCMOLT_CFG_INIT(&nni_cfg, nni_interface, nni_key);
1499 BCMOLT_FIELD_SET_PRESENT(&nni_cfg.data, nni_interface_cfg_data, state);
1500 err = bcmolt_cfg_get(dev_id, &nni_cfg.hdr);
1501 *state = nni_cfg.data.state;
1502 return err;
1503}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001504
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001505Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
1506 bcmos_errno err = BCM_ERR_OK;
1507 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1508 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1509 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001510
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001511 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001512 if (err == BCM_ERR_OK) {
1513 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001514 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001515 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1516 CreateDefaultSched(intf_id, upstream);
1517 CreateDefaultQueue(intf_id, upstream);
1518 return Status::OK;
1519 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1520 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1521 return Status::OK;
1522 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001523 }
1524
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001525 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1526 if (set_state) {
1527 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1528 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1529 } else {
1530 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1531 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1532 }
1533 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1534 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001535 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1536 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001537 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1538 }
1539 else {
1540 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1541 if (set_state) {
1542 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1543 CreateDefaultSched(intf_id, upstream);
1544 CreateDefaultQueue(intf_id, upstream);
1545 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001546 }
1547
1548 return Status::OK;
1549}
1550
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001551Status DisablePonIf_(uint32_t intf_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001552 bcmolt_pon_interface_cfg interface_obj;
1553 bcmolt_pon_interface_key interface_key;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001554
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001555 interface_key.pon_ni = intf_id;
1556 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
1557 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1558 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001559 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001560 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d, err = %s\n", intf_id, bcmos_strerror(err));
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001561 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001562 }
1563
1564 return Status::OK;
1565}
1566
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001567Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001568 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001569 bcmos_errno err = BCM_ERR_OK;
1570 bcmolt_onu_cfg onu_cfg;
1571 bcmolt_onu_key onu_key;
1572 bcmolt_serial_number serial_number; /**< ONU serial number */
1573 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001574
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001575 onu_key.onu_id = onu_id;
1576 onu_key.pon_ni = intf_id;
1577 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1578 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1579 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001580 if (err == BCM_ERR_OK) {
1581 if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING ||
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001582 onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) ||
1583 (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_INACTIVE &&
1584 onu_cfg.data.onu_old_state == BCMOLT_ONU_STATE_NOT_CONFIGURED))
1585 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001586 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001587
1588 OPENOLT_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001589vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001590 vendor_specific_to_str(vendor_specific).c_str(), pir);
1591
1592 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1593 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1594 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1595 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1596 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1597 /*set burst and data profiles to fec disabled*/
1598 if (board_technology == "XGS-PON") {
1599 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1600 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1601 } else if (board_technology == "GPON") {
1602 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1603 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1604 }
1605 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1606 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001607 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to set activate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001608 return bcm_to_grpc_err(err, "Failed to activate ONU");
1609 }
1610
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001611 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001612}
1613
Jonathan Davis70c21812018-07-19 15:32:10 -04001614Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1615 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001616 bcmos_errno err = BCM_ERR_OK;
1617 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1618 bcmolt_onu_cfg onu_cfg;
1619 bcmolt_onu_key onu_key; /**< Object key. */
1620 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001621
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001622 onu_key.onu_id = onu_id;
1623 onu_key.pon_ni = intf_id;
1624 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1625 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1626 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001627 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001628 switch (onu_state) {
1629 case BCMOLT_ONU_OPERATION_ACTIVE:
1630 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001631 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001632 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1633 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1634 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001635 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to deactivate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001636 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1637 }
1638 break;
1639 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001640 }
1641
1642 return Status::OK;
1643}
1644
1645Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001646 const char *vendor_id, const char *vendor_specific) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001647
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001648 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 -05001649 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1650
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001651 // Need to deactivate before removing it (BAL rules)
1652
1653 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1654 // Sleep to allow the state to propagate
1655 // We need the subscriber terminal object to be admin down before removal
1656 // Without sleep the race condition is lost by ~ 20 ms
1657 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1658
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001659 // TODO: Delete the schedulers and queues.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001660
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001661 bcmolt_onu_cfg cfg_obj;
1662 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001663
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001664 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 -04001665 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001666
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001667 key.onu_id = onu_id;
1668 key.pon_ni = intf_id;
1669 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001670
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001671 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001672 if (err != BCM_ERR_OK)
1673 {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001674 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL subscriber_terminal_id %d, Interface ID %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Jonathan Davis70c21812018-07-19 15:32:10 -04001675 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1676 }
1677
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001678 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001679}
1680
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001681#define MAX_CHAR_LENGTH 20
1682#define MAX_OMCI_MSG_LENGTH 44
1683Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001684 bcmolt_bin_str buf = {};
1685 bcmolt_onu_cpu_packets omci_cpu_packets;
1686 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001687
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001688 key.pon_ni = intf_id;
1689 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001690
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001691 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1692 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1693 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001694
1695 // ???
1696 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1697 buf.len = MAX_OMCI_MSG_LENGTH;
1698 } else {
1699 buf.len = pkt.size()/2;
1700 }
1701
1702 /* Send the OMCI packet using the BAL remote proxy API */
1703 uint16_t idx1 = 0;
1704 uint16_t idx2 = 0;
1705 uint8_t arraySend[buf.len];
1706 char str1[MAX_CHAR_LENGTH];
1707 char str2[MAX_CHAR_LENGTH];
1708 memset(&arraySend, 0, buf.len);
1709
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001710 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1711 sprintf(str1,"%c", pkt[idx1]);
1712 sprintf(str2,"%c", pkt[++idx1]);
1713 strcat(str1,str2);
1714 arraySend[idx2] = strtol(str1, NULL, 16);
1715 }
1716
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001717 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1718 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001719
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001720 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1721 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1722 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001723
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001724 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001725 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001726 OPENOLT_LOG(ERROR, openolt_log_id, "Error sending OMCI message to ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001727 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001728 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001729 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 -05001730 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001731 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001732 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001733
1734 return Status::OK;
1735}
1736
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001737Status 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 +00001738 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1739 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1740 bcmolt_bin_str buf = {};
1741 bcmolt_gem_port_id gem_port_id_array[1];
1742 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001743
Craig Lutgen967a1d02018-11-27 10:41:51 -06001744 if (port_no > 0) {
1745 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001746 if (gemport_id == 0) {
1747 bcmos_fastlock_lock(&data_lock);
1748 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1749 // Pick any flow that is mapped with the same port_no.
1750 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1751 if (it != port_to_flows.end() && !it->second.empty()) {
1752 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1753 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1754 if (fit != flowid_to_gemport.end()) {
1755 found = true;
1756 gemport_id = fit->second;
1757 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001758 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001759 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001760
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001761 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001762 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 -08001763 onu_id, port_no, intf_id);
1764 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1765 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001766 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 -08001767 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001768 }
1769
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001770 gem_port_id_array[0] = gemport_id;
1771 gem_port_list.len = 1;
1772 gem_port_list.arr = gem_port_id_array;
1773 buf.len = pkt.size();
1774 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1775 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1776
1777 /* init the API struct */
1778 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1779 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1780 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1781 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1782 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1783
1784 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1785 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1786
1787 /* call API */
1788 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001789 }
1790 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001791 //TODO: Port No is 0, it is coming sender requirement.
1792 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1793 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001794 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001795 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001796
1797 return Status::OK;
1798}
1799
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001800Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001801 bcmolt_flow_key key = {}; /* declare key */
1802 bcmolt_bin_str buffer = {};
1803 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001804
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001805 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1806 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001807
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001808 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1809 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1810 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1811 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1812 key.flow_id = flow_id;
1813 else {
1814 if (flow_id_counters != 0) {
1815 for (int flowid=0; flowid < flow_id_counters; flowid++) {
1816 int flow_index = flow_id_data[flowid][0];
1817 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1818 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1819 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1820 key.flow_id = flow_index;
1821 break;
1822 }
1823 }
1824 }
1825 else {
1826 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1827 }
1828 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001829
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001830 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001831
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001832 /* Initialize the API struct. */
1833 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001834
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001835 buffer.len = pkt.size();
1836 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1837 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1838 if (buffer.arr == NULL) {
1839 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1840 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1841 }
1842 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1843
1844 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1845 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001846 OPENOLT_LOG(ERROR, openolt_log_id, "Error sending packets via nni port %d, flow_id %d, err = %s\n", intf_id, key.flow_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001847 } else {
1848 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1849 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001850
1851 return Status::OK;
1852}
1853
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001854uint32_t GetPortNum_(uint32_t flow_id) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001855 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001856 uint32_t port_no = 0;
1857 std::map<uint32_t, uint32_t >::const_iterator it = flowid_to_port.find(flow_id);
1858 if (it != flowid_to_port.end()) {
1859 port_no = it->second;
1860 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001861 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001862 return port_no;
1863}
1864
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001865#define FLOW_LOG(level,msg,err) \
1866 do { \
1867 OPENOLT_LOG(level, openolt_log_id, "--------> %s (flow_id %d) err: %d <--------\n", msg, key.flow_id, err); \
1868 OPENOLT_LOG(level, openolt_log_id, "intf_id %d, onu_id %d, uni_id %d, port_no %u, cookie %"PRIu64"\n", \
1869 access_intf_id, onu_id, uni_id, port_no, cookie); \
1870 OPENOLT_LOG(level, openolt_log_id, "flow_type %s, queue_id %d, sched_id %d\n", flow_type.c_str(), \
1871 cfg.data.egress_qos.u.fixed_queue.queue_id, cfg.data.egress_qos.tm_sched.id); \
1872 OPENOLT_LOG(level, openolt_log_id, "Ingress(intfd_type %s, intf_id %d), Egress(intf_type %s, intf_id %d)\n", \
1873 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), cfg.data.ingress_intf.intf_id, \
1874 GET_FLOW_INTERFACE_TYPE(cfg.data.egress_intf.intf_type), cfg.data.egress_intf.intf_id); \
1875 OPENOLT_LOG(level, openolt_log_id, "classifier(o_vid %d, o_pbits %d, i_vid %d, i_pbits %d, ether type 0x%x)\n", \
1876 c_val.o_vid, c_val.o_pbits, c_val.i_vid, c_val.i_pbits, classifier.eth_type()); \
1877 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", \
1878 c_val.ip_proto, gemport_id, c_val.src_port, c_val.dst_port, GET_PKT_TAG_TYPE(c_val.pkt_tag_type)); \
1879 OPENOLT_LOG(level, openolt_log_id, "action(cmds_bitmask %s, o_vid %d, o_pbits %d, i_vid %d, i_pbits %d)\n\n", \
1880 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 -04001881 } while(0)
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001882
1883#define FLOW_PARAM_LOG() \
1884 do { \
1885 OPENOLT_LOG(INFO, openolt_log_id, "--------> flow comparison (now before) <--------\n"); \
1886 OPENOLT_LOG(INFO, openolt_log_id, "flow_id (%d %d)\n", \
1887 key.flow_id, flow_index); \
1888 OPENOLT_LOG(INFO, openolt_log_id, "onu_id (%d %lu)\n", \
1889 cfg.data.onu_id , get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)); \
1890 OPENOLT_LOG(INFO, openolt_log_id, "type (%d %lu)\n", \
1891 key.flow_type, get_flow_status(flow_index, flow_id_data[flowid][1], FLOW_TYPE)); \
1892 OPENOLT_LOG(INFO, openolt_log_id, "svc_port_id (%d %lu)\n", \
1893 cfg.data.svc_port_id, get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)); \
1894 OPENOLT_LOG(INFO, openolt_log_id, "priority (%d %lu)\n", \
1895 cfg.data.priority, get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)); \
1896 OPENOLT_LOG(INFO, openolt_log_id, "cookie (%lu %lu)\n", \
1897 cfg.data.cookie, get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)); \
1898 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf_type (%s %s)\n", \
1899 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), \
1900 GET_FLOW_INTERFACE_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE))); \
1901 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf id (%d %lu)\n", \
1902 cfg.data.ingress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)); \
1903 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_type (%d %lu)\n", \
1904 cfg.data.egress_intf.intf_type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)); \
1905 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_id (%d %lu)\n", \
1906 cfg.data.egress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)); \
1907 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_vid (%d %lu)\n", \
1908 c_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)); \
1909 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_pbits (%d %lu)\n", \
1910 c_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)); \
1911 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_vid (%d %lu)\n", \
1912 c_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)); \
1913 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_pbits (%d %lu)\n", \
1914 c_val.i_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)); \
1915 OPENOLT_LOG(INFO, openolt_log_id, "classifier ether_type (0x%x 0x%lx)\n", \
1916 c_val.ether_type , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)); \
1917 OPENOLT_LOG(INFO, openolt_log_id, "classifier ip_proto (%d %lu)\n", \
1918 c_val.ip_proto , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)); \
1919 OPENOLT_LOG(INFO, openolt_log_id, "classifier src_port (%d %lu)\n", \
1920 c_val.src_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)); \
1921 OPENOLT_LOG(INFO, openolt_log_id, "classifier dst_port (%d %lu)\n", \
1922 c_val.dst_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)); \
1923 OPENOLT_LOG(INFO, openolt_log_id, "classifier pkt_tag_type (%s %s)\n", \
1924 GET_PKT_TAG_TYPE(c_val.pkt_tag_type), \
1925 GET_PKT_TAG_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE))); \
1926 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos type (%d %lu)\n", \
1927 cfg.data.egress_qos.type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)); \
1928 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos queue_id (%d %lu)\n", \
1929 cfg.data.egress_qos.u.fixed_queue.queue_id, \
1930 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)); \
1931 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos sched_id (%d %lu)\n", \
1932 cfg.data.egress_qos.tm_sched.id, \
1933 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)); \
1934 OPENOLT_LOG(INFO, openolt_log_id, "classifier cmds_bitmask (%s %s)\n", \
1935 get_flow_acton_command(a_val.cmds_bitmask), \
1936 get_flow_acton_command(get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_CMDS_BITMASK))); \
1937 OPENOLT_LOG(INFO, openolt_log_id, "action o_vid (%d %lu)\n", \
1938 a_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)); \
1939 OPENOLT_LOG(INFO, openolt_log_id, "action i_vid (%d %lu)\n", \
1940 a_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)); \
1941 OPENOLT_LOG(INFO, openolt_log_id, "action o_pbits (%d %lu)\n", \
1942 a_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)); \
1943 OPENOLT_LOG(INFO, openolt_log_id, "action i_pbits (%d %lu)\n\n", \
1944 a_val.i_pbits, get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)); \
1945 } while(0)
1946
1947#define FLOW_CHECKER
1948//#define SHOW_FLOW_PARAM
1949
Craig Lutgen967a1d02018-11-27 10:41:51 -06001950Status 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 +00001951 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001952 int32_t alloc_id, int32_t network_intf_id,
1953 int32_t gemport_id, const ::openolt::Classifier& classifier,
Craig Lutgen967a1d02018-11-27 10:41:51 -06001954 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001955 bcmolt_flow_cfg cfg;
1956 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001957 int32_t o_vid = -1;
1958 bool single_tag = false;
1959 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001960 bcmolt_classifier c_val = { };
1961 bcmolt_action a_val = { };
1962 bcmolt_tm_queue_ref tm_val = { };
1963 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001964 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001965
1966 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001967 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001968 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001969 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001970 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001971 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001972 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001973 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001974 }
1975
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001976 BCMOLT_CFG_INIT(&cfg, flow, key);
1977 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001978
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001979 if (access_intf_id >= 0 && network_intf_id >= 0) {
1980 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1981 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1982 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
1983 if (classifier.eth_type() == EAP_ETHER_TYPE || //EAPOL packet
1984 (classifier.ip_proto() == 17 && classifier.src_port() == 68 && classifier.dst_port() == 67)) { //DHCP packet
1985 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
1986 } else {
1987 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1988 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
1989 }
1990 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1991 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1992 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1993 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1994 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
1995 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301996 } else if (access_intf_id < 0 ) {
1997 // This is the case for packet trap from NNI flow.
1998 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1999 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
2000 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002001 } else {
2002 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
2003 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
2004 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002005
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302006
Shad Ansari39739bc2018-09-13 21:38:37 +00002007 if (onu_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002008 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00002009 }
2010 if (gemport_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002011 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00002012 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002013 if (gemport_id >= 0 && port_no != 0) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002014 bcmos_fastlock_lock(&data_lock);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002015 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002016 port_to_flows[port_no].insert(key.flow_id);
2017 flowid_to_gemport[key.flow_id] = gemport_id;
2018 }
2019 else
2020 {
2021 flowid_to_port[key.flow_id] = port_no;
2022 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002023 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002024 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002025 if (priority_value >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002026 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
Shad Ansari39739bc2018-09-13 21:38:37 +00002027 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002028
2029 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002030 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002031 if (classifier.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002032 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_tpid 0x%04x\n", classifier.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002033 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_tpid, classifier.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002034 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002035 */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002036 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002037 if (classifier.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002038 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_tpid 0x%04x\n", classifier.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002039 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_tpid, classifier.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002040 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002041 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002042
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002043 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002044 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002045 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
2046 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002047 }
2048
2049 /*
2050 if (classifier.dst_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002051 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_mac, classifier.dst_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002052 }
2053
2054 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002055 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002056 }
2057 */
2058
2059 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002060 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
2061 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002062 }
2063
2064 /*
2065 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002066 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002067 }
2068
2069 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002070 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002071 }
2072 */
2073
2074 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002075 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
2076 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002077 }
2078
2079 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002080 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
2081 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002082 }
2083
2084 if (!classifier.pkt_tag_type().empty()) {
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302085 if (cfg.data.ingress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_NNI && \
2086 cfg.data.egress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
2087 // This is case where packet traps from NNI port. As per Broadcom workaround
2088 // suggested in CS8839882, the packet_tag_type has to be 'untagged' irrespective
2089 // of what the actual tag type is. Otherwise, packet trap from NNI wont work.
2090 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2091 } else {
2092 if (classifier.o_vid()) {
2093 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
2094 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
2095 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002096
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302097 if (classifier.i_vid()) {
2098 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
2099 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
2100 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002101
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302102 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
2103 if (classifier.pkt_tag_type().compare("untagged") == 0) {
2104 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2105 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
2106 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
2107 single_tag = true;
2108
2109 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
YJbbeeff42019-11-21 16:22:50 -05002110 if(classifier.o_pbits()){
2111 //According to makeOpenOltClassifierField in voltha-openolt-adapter, o_pbits 0xFF means PCP value 0.
2112 //0 vlaue of o_pbits means o_pbits is not available
2113 if(0xFF == classifier.o_pbits()){
2114 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, 0);
2115 }
2116 else{
2117 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2118 }
2119 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302120 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
2121 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
2122
2123 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
YJbbeeff42019-11-21 16:22:50 -05002124 if(classifier.o_pbits()){
2125 if(0xFF == classifier.o_pbits()){
2126 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, 0);
2127 }
2128 else{
2129 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2130 }
2131 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302132 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002133 }
2134 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002135 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002136 }
2137
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002138 if (cfg.data.egress_intf.intf_type != BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002139 const ::openolt::ActionCmd& cmd = action.cmd();
2140
2141 if (cmd.add_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002142 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
2143 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002144 }
2145
2146 if (cmd.remove_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002147 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
2148 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002149 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002150 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002151 if (cmd.trap_to_host()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002152 OPENOLT_LOG(INFO, openolt_log_id, "action trap-to-host\n");
Craig Lutgen19512312018-11-02 10:14:46 -05002153 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002154 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002155 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002156 if (action.o_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002157 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002158 o_vid = action.o_vid();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002159 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002160 }
2161
2162 if (action.o_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002163 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
2164 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002165 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002166 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002167 if (action.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002168 OPENOLT_LOG(INFO, openolt_log_id, "action o_tpid=0x%04x\n", action.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002169 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_tpid, action.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002170 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002171 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002172 if (action.i_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002173 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
2174 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002175 }
2176
2177 if (action.i_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002178 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
2179 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002180 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002181 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002182 if (action.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002183 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_tpid=0x%04x\n", action.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002184 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_tpid, action.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002185 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002186 */
2187 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002188 }
2189
Shad Ansari39739bc2018-09-13 21:38:37 +00002190 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002191 if(single_tag && ether_type == EAP_ETHER_TYPE) {
2192 tm_val.sched_id = (flow_type.compare(upstream) == 0) ? \
2193 get_default_tm_sched_id(network_intf_id, upstream) : \
2194 get_default_tm_sched_id(access_intf_id, downstream);
2195 tm_val.queue_id = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002196
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002197 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2198 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2199 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002200
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002201 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2202 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2203 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2204 } else {
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002205 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002206 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
2207 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
2208
2209 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2210 // Queue 0 on DS subscriber scheduler
2211 tm_val.queue_id = 0;
2212
2213 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2214 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2215 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2216
2217 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2218 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2219 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2220
2221 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2222 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2223 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2224
2225 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2226 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2227 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2228 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2229
2230 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2231 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2232 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2233 }
2234 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2235 // NNI Scheduler ID
2236 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2237 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2238 // Queue 0 on NNI scheduler
2239 tm_val.queue_id = 0;
2240 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2241 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2242 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2243
2244 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2245 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2246 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2247
2248 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2249 /* Fetch TM QMP ID mapped to US NNI scheduler */
2250 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2251 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2252 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2253 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2254 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2255
2256 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2257 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2258 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2259 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002260 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002261 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302262 } else {
2263 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2264 tm_val.queue_id = 0;
2265
2266 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2267 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2268 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2269
2270 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2271 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2272 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002273 }
2274
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002275 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
2276 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2277#ifdef FLOW_CHECKER
2278 //Flow Checker, To avoid duplicate flow.
2279 if (flow_id_counters != 0) {
2280 bool b_duplicate_flow = false;
2281 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2282 int flow_index = flow_id_data[flowid][0];
2283 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)) && \
2284 (key.flow_type == flow_id_data[flowid][1]) && \
2285 (cfg.data.svc_port_id == get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)) && \
2286 (cfg.data.priority == get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)) && \
2287 (cfg.data.cookie == get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)) && \
2288 (cfg.data.ingress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE)) && \
2289 (cfg.data.ingress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)) && \
2290 (cfg.data.egress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)) && \
2291 (cfg.data.egress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)) && \
2292 (c_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)) && \
2293 (c_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)) && \
2294 (c_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)) && \
2295 (c_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)) && \
2296 (c_val.ether_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)) && \
2297 (c_val.ip_proto == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)) && \
2298 (c_val.src_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)) && \
2299 (c_val.dst_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)) && \
2300 (c_val.pkt_tag_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE)) && \
2301 (cfg.data.egress_qos.type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)) && \
2302 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)) && \
2303 (cfg.data.egress_qos.tm_sched.id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)) && \
2304 (a_val.cmds_bitmask == get_flow_status(flowid, flow_id_data[flowid][1], ACTION_CMDS_BITMASK)) && \
2305 (a_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)) && \
2306 (a_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)) && \
2307 (a_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)) && \
2308 (a_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)) && \
2309 (cfg.data.state == get_flow_status(flowid, flow_id_data[flowid][1], STATE));
2310#ifdef SHOW_FLOW_PARAM
2311 // Flow Parameter
2312 FLOW_PARAM_LOG();
2313#endif
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002314
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002315 if (b_duplicate_flow) {
2316 FLOW_LOG(WARNING, "Flow duplicate", 0);
2317 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2318 }
2319 }
2320 }
2321#endif
2322
2323 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2324 if (err) {
2325 FLOW_LOG(ERROR, "Flow add failed", err);
2326 return bcm_to_grpc_err(err, "flow add failed");
2327 } else {
2328 FLOW_LOG(INFO, "Flow add ok", err);
2329 bcmos_fastlock_lock(&data_lock);
2330 flow_id_data[flow_id_counters][0] = key.flow_id;
2331 flow_id_data[flow_id_counters][1] = key.flow_type;
2332 flow_id_counters += 1;
2333 bcmos_fastlock_unlock(&data_lock, 0);
2334 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002335
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002336 return Status::OK;
2337}
2338
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002339Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2340
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002341 bcmolt_flow_cfg cfg;
2342 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002343
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002344 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002345 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002346 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002347 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002348 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002349 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002350 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002351 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002352 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2353 }
2354
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002355 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002356 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002357 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002358 flowid_to_gemport.erase(key.flow_id);
2359 port_to_flows[port_no].erase(key.flow_id);
2360 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2361 }
2362 else
2363 {
2364 flowid_to_port.erase(key.flow_id);
2365 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002366 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002367
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002368 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002369
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002370 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002371 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002372 OPENOLT_LOG(ERROR, openolt_log_id, "Error while removing %s flow, flow_id=%d, err = %s\n", flow_type.c_str(), flow_id, bcmos_strerror(err));
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002373 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2374 }
2375
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002376 bcmos_fastlock_lock(&data_lock);
2377 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2378 if (flow_id_data[flowid][0] == flow_id && flow_id_data[flowid][1] == key.flow_type) {
2379 flow_id_counters -= 1;
2380 for (int i=flowid; i < flow_id_counters; i++) {
2381 flow_id_data[i][0] = flow_id_data[i + 1][0];
2382 flow_id_data[i][1] = flow_id_data[i + 1][1];
2383 }
2384 break;
2385 }
2386 }
2387 bcmos_fastlock_unlock(&data_lock, 0);
2388
2389 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002390 return Status::OK;
2391}
2392
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002393bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2394 bcmos_errno err;
2395 bcmolt_tm_sched_cfg tm_sched_cfg;
2396 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2397 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2398
Jason Huangbf45ffb2019-10-30 17:29:02 +08002399 //check TM scheduler has configured or not
2400 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2401 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
2402 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
2403 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002404 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query TM scheduler, err = %s\n",bcmos_strerror(err));
Jason Huangbf45ffb2019-10-30 17:29:02 +08002405 return err;
2406 }
2407 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2408 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2409 return BCM_ERR_OK;
2410 }
2411
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002412 // bcmbal_tm_sched_owner
2413 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2414
2415 /**< The output of the tm_sched object instance */
2416 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2417
2418 if (direction.compare(upstream) == 0) {
2419 // In upstream it is NNI scheduler
2420 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2421 } else if (direction.compare(downstream) == 0) {
2422 // In downstream it is PON scheduler
2423 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2424 }
2425
2426 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2427
2428 // bcmbal_tm_sched_type
2429 // set the deafult policy to strict priority
2430 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2431
2432 // num_priorities: Max number of strict priority scheduling elements
2433 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
2434
2435 // bcmbal_tm_shaping
2436 uint32_t cir = 1000000;
2437 uint32_t pir = 1000000;
2438 uint32_t burst = 65536;
2439 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in %s pir=%u, burst=%u\n",
2440 direction.c_str(), pir, burst);
2441 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2442 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2443 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2444 // BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2445 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2446 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
2447
2448 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2449 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002450 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2451 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002452 return err;
2453 }
2454
2455 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2456 direction.c_str(), tm_sched_key.id, intf_id);
2457 return BCM_ERR_OK;
2458}
2459
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002460bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
2461 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2462 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002463
2464 bcmos_errno err;
2465
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002466 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002467 bcmolt_tm_sched_cfg tm_sched_cfg;
2468 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2469 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002470
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002471 // bcmbal_tm_sched_owner
2472 // In downstream it is sub_term scheduler
2473 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002474
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002475 /**< The output of the tm_sched object instance */
2476 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002477
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002478 // bcmbal_tm_sched_parent
2479 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2480 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2481 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_param.u.priority.priority, priority);
2482 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
2483 be achieved using the' virtual' type of attachment.
2484 tm_sched_owner.u.sub_term.intf_id = intf_id;
2485 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2486 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002487
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002488 // bcmbal_tm_sched_type
2489 // set the deafult policy to strict priority
2490 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002491
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002492 // num_priorities: Max number of strict priority scheduling elements
2493 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002494
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002495 // bcmbal_tm_shaping
2496 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2497 uint32_t cir = tf_sh_info.cir();
2498 uint32_t pir = tf_sh_info.pir();
2499 uint32_t burst = tf_sh_info.pbs();
2500 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2501 cir, pir, burst);
2502 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2503 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2504 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2505 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2506 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2507 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002508 }
2509
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002510 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002511 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002512 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002513intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2514port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002515 return err;
2516 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002517 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2518uni_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 -08002519
2520 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002521 bcmolt_itupon_alloc_cfg cfg;
2522 bcmolt_itupon_alloc_key key = { };
2523 key.pon_ni = intf_id;
2524 key.alloc_id = alloc_id;
2525 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
2526 int pir_bw = tf_sh_info.pir();
2527 int cir_bw = tf_sh_info.cir();
2528 //offset to match bandwidth granularity
2529 int offset_pir_bw = pir_bw%bw_granularity;
2530 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002531
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002532 pir_bw = pir_bw - offset_pir_bw;
2533 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002534
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002535 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002536
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002537 switch (additional_bw) {
2538 case 2: //AdditionalBW_BestEffort
2539 if (pir_bw == 0) {
2540 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2541%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2542 } else if (pir_bw < cir_bw) {
2543 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2544bandwidth (%d)\n", pir_bw, cir_bw);
2545 return BCM_ERR_PARM;
2546 } else if (pir_bw == cir_bw) {
2547 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2548bandwidth for additional bandwidth eligibility of type best_effort\n");
2549 return BCM_ERR_PARM;
2550 }
2551 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2552 break;
2553 case 1: //AdditionalBW_NA
2554 if (pir_bw == 0) {
2555 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2556%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2557 return BCM_ERR_PARM;
2558 } else if (cir_bw == 0) {
2559 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2560additional bandwidth eligibility of type Non-Assured (NA)\n");
2561 return BCM_ERR_PARM;
2562 } else if (pir_bw < cir_bw) {
2563 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2564bandwidth (%d)\n", pir_bw, cir_bw);
2565 return BCM_ERR_PARM;
2566 } else if (pir_bw == cir_bw) {
2567 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2568bandwidth for additional bandwidth eligibility of type non_assured\n");
2569 return BCM_ERR_PARM;
2570 }
2571 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2572 break;
2573 case 0: //AdditionalBW_None
2574 if (pir_bw == 0) {
2575 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
257616000 bytes/sec\n");
2577 return BCM_ERR_PARM;
2578 } else if (cir_bw == 0) {
2579 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2580for additional bandwidth eligibility of type None\n");
2581 return BCM_ERR_PARM;
2582 } else if (pir_bw > cir_bw) {
2583 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2584for additional bandwidth eligibility of type None\n");
2585 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2586bandwidth in None eligibility\n", pir_bw);
2587 cir_bw = pir_bw;
2588 } else if (pir_bw < cir_bw) {
2589 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2590bandwidth (%d)\n", pir_bw, cir_bw);
2591 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2592bandwidth in None eligibility\n", pir_bw);
2593 cir_bw = pir_bw;
2594 }
2595 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2596 break;
2597 default:
2598 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002599 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002600 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2601 in a fine granularity. */
2602 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2603 /* Fixed Bandwidth with no critical requirement of shaping */
2604 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2605 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2606 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2607 /* Maximum allocated bandwidth allowed for this alloc ID */
2608 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2609 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2610 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
2611 for skipped allocations during quiet window */
2612 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2613 /**< Allocation Profile index for CBR non-RT Bandwidth */
2614 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2615 /**< Allocation Profile index for CBR RT Bandwidth */
2616 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2617 /**< Alloc ID Weight used in case of Extended DBA mode */
2618 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2619 /**< Alloc ID Priority used in case of Extended DBA mode */
2620 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2621 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002622
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002623 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002624 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002625 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002626port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002627 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002628 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002629 OPENOLT_LOG(INFO, openolt_log_id, "Create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d, port_no %u, \
2630alloc_id %d\n", intf_id,onu_id,uni_id,port_no,alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002631 }
2632
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002633 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002634}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002635
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002636Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2637 uint32_t intf_id = traffic_scheds->intf_id();
2638 uint32_t onu_id = traffic_scheds->onu_id();
2639 uint32_t uni_id = traffic_scheds->uni_id();
2640 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002641 std::string direction;
2642 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002643 tech_profile::SchedulerConfig sched_config;
2644 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002645 uint32_t priority;
2646 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002647 tech_profile::SchedulingPolicy sched_policy;
2648 tech_profile::TrafficShapingInfo traffic_shaping_info;
2649 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002650
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002651 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2652 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002653
2654 direction = GetDirection(traffic_sched.direction());
2655 if (direction.compare("direction-not-supported") == 0)
2656 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2657
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002658 alloc_id = traffic_sched.alloc_id();
2659 sched_config = traffic_sched.scheduler();
2660 additional_bw = sched_config.additional_bw();
2661 priority = sched_config.priority();
2662 weight = sched_config.weight();
2663 sched_policy = sched_config.sched_policy();
2664 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2665 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2666 sched_policy, traffic_shaping_info);
2667 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002668 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002669 return bcm_to_grpc_err(err, "Failed to create scheduler");
2670 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002671 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002672 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002673}
Jonathan Davis70c21812018-07-19 15:32:10 -04002674
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002675bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002676
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002677 bcmos_errno err;
Jonathan Davis70c21812018-07-19 15:32:10 -04002678
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002679 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002680 bcmolt_itupon_alloc_cfg cfg;
2681 bcmolt_itupon_alloc_key key = { };
2682 key.pon_ni = intf_id;
2683 key.alloc_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002684
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002685 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
2686 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2687 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002688 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2689 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002690 return err;
2691 }
2692 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, intf_id %d, alloc_id %d\n", \
2693 direction.c_str(), intf_id, alloc_id);
2694 } else if (direction == downstream) {
2695 bcmolt_tm_sched_cfg cfg;
2696 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002697
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002698 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
2699 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2700 } else {
2701 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2702 return BCM_ERR_OK;
2703 }
2704 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2705 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2706 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002707 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
2708intf_id %d, onu_id %d, err = %s\n", direction.c_str(), key.id, intf_id, onu_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002709 return err;
2710 }
2711 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n", \
2712 direction.c_str(), key.id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002713 }
2714
2715 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002716 return BCM_ERR_OK;
2717}
2718
2719Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2720 uint32_t intf_id = traffic_scheds->intf_id();
2721 uint32_t onu_id = traffic_scheds->onu_id();
2722 uint32_t uni_id = traffic_scheds->uni_id();
2723 std::string direction;
2724 bcmos_errno err;
2725
2726 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2727 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002728
2729 direction = GetDirection(traffic_sched.direction());
2730 if (direction.compare("direction-not-supported") == 0)
2731 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2732
2733 int alloc_id = traffic_sched.alloc_id();
2734 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002735 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002736 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002737 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2738 }
2739 }
2740 return Status::OK;
2741}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002742
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002743bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2744 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002745 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002746 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2747 bcmolt_tm_qmp_key tm_qmp_key;
2748 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002749
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002750 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2751 if (tm_qmp_id == -1) {
2752 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 -08002753 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002754
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002755 tm_qmp_key.id = tm_qmp_id;
2756 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2757 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2758 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002759
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002760 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2761 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2762 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
2763 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2764 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002765
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002766 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002767 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002768 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2769 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002770 return err;
2771 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002772
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002773 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2774 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002775 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002776}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002777
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002778bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2779 bcmos_errno err;
2780 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2781 bcmolt_tm_qmp_key tm_qmp_key;
2782 tm_qmp_key.id = tm_qmp_id;
2783
2784 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2785 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2786 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002787 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2788 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002789 return err;
2790 }
2791
2792 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2793 tm_qmp_key.id);
2794 return BCM_ERR_OK;
2795}
2796
2797bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2798 bcmos_errno err;
2799
2800 /* Create 4 Queues on given PON/NNI scheduler */
2801 for (int queue_id = 0; queue_id < 4; queue_id++) {
2802 bcmolt_tm_queue_cfg tm_queue_cfg;
2803 bcmolt_tm_queue_key tm_queue_key = {};
2804 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2805 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002806 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2807 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2808 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002809
2810 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2811 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2812 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2813
2814 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2815 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002816 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s tm queue, id %d, sched_id %d, tm_q_set_id %d, err = %s\n", \
2817 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002818 return err;
2819 }
2820
2821 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2822 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2823 }
2824 return BCM_ERR_OK;
2825}
2826
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002827bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2828 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002829 bcmos_errno err;
2830 bcmolt_tm_queue_cfg cfg;
2831 bcmolt_tm_queue_key key = { };
2832 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
2833gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
2834
2835 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2836 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2837
2838 if (priority > 7) {
2839 return BCM_ERR_RANGE;
2840 }
2841
2842 /* FIXME: The upstream queues have to be created once only.
2843 The upstream queues on the NNI scheduler are shared by all subscribers.
2844 When the first scheduler comes in, the queues get created, and are re-used by all others.
2845 Also, these queues should be present until the last subscriber exits the system.
2846 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2847
2848 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2849 for each GEM in TECH PROFILE */
2850 key.id = queue_id_list[priority];
2851
2852 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2853 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2854 key.id = 0;
2855 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2856 }
2857 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2858 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2859 }
2860 else {
2861 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2862 }
2863
2864 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2865
2866 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2867 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2868
2869 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2870 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002871 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
2872sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n", \
2873 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002874 return err;
2875 }
2876
2877 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2878intf_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);
2879 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002880}
2881
2882Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2883 uint32_t intf_id = traffic_queues->intf_id();
2884 uint32_t onu_id = traffic_queues->onu_id();
2885 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002886 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002887 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002888 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002889 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 +00002890
2891 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2892 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2893 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2894 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2895 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2896
2897 direction = GetDirection(traffic_queue.direction());
2898 if (direction.compare("direction-not-supported") == 0)
2899 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2900
2901 queues_priority_q[i] = traffic_queue.priority();
2902 queues_pbit_map[i] = traffic_queue.pbit_map();
2903 }
2904
2905 std::vector<uint32_t> tmq_map_profile(8, 0);
2906 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2907 queues_priority_q, COUNT_OF(queues_priority_q));
2908 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2909 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2910
2911 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2912 if (tm_qmp_id == -1) {
2913 CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2914 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2915 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2916 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2917 }
2918 }
2919
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002920 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2921 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002922
2923 direction = GetDirection(traffic_queue.direction());
2924 if (direction.compare("direction-not-supported") == 0)
2925 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2926
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002927 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 +00002928
Girish Gowdruf26cf882019-05-01 23:47:58 -07002929 // If the queue exists already, lets not return failure and break the loop.
2930 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002931 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002932 return bcm_to_grpc_err(err, "Failed to create queue");
2933 }
2934 }
2935 return Status::OK;
2936}
2937
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002938bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2939 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002940 bcmolt_tm_queue_cfg cfg;
2941 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002942 bcmos_errno err;
2943
2944 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002945 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
2946 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2947 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002948 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002949 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 -08002950 return BCM_ERR_OK;
2951 }
2952 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002953 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2954 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002955 return BCM_ERR_OK;
2956 }
2957
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002958 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2959 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2960 // Reset the queue id to 0 when using fixed queue.
2961 key.id = 0;
2962 }
2963 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2964 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2965 }
2966 else {
2967 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2968 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002969
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002970 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2971 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002972 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002973 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2974tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2975 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002976 return err;
2977 }
2978
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002979 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2980intf_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 -08002981
2982 return BCM_ERR_OK;
2983}
2984
2985Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2986 uint32_t intf_id = traffic_queues->intf_id();
2987 uint32_t onu_id = traffic_queues->onu_id();
2988 uint32_t uni_id = traffic_queues->uni_id();
2989 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002990 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002991 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002992 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002993 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 +00002994
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002995 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2996 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002997
2998 direction = GetDirection(traffic_queue.direction());
2999 if (direction.compare("direction-not-supported") == 0)
3000 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
3001
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003002 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 -08003003 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003004 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003005 return bcm_to_grpc_err(err, "Failed to remove queue");
3006 }
Jonathan Davis70c21812018-07-19 15:32:10 -04003007 }
3008
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003009 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))) {
3010 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
3011 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
3012
3013 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
3014 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
3015 RemoveTrafficQueueMappingProfile(tm_qmp_id);
3016 }
3017 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003018 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04003019 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04003020}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003021
3022Status check_connection() {
3023 int maxTrials = 60;
3024 while (!bcmolt_api_conn_mgr_is_connected(dev_id)) {
3025 sleep(1);
3026 if (--maxTrials == 0)
3027 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check connection failed");
3028 else
3029 OPENOLT_LOG(INFO, openolt_log_id, "waiting for daemon connection ...\n");
3030 }
3031 OPENOLT_LOG(INFO, openolt_log_id, "daemon is connected\n");
3032 return Status::OK;
3033}
3034
3035Status check_bal_ready() {
3036 bcmos_errno err;
3037 int maxTrials = 30;
3038 bcmolt_olt_cfg olt_cfg = { };
3039 bcmolt_olt_key olt_key = { };
3040
3041 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
3042 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
3043
3044 while (olt_cfg.data.bal_state != BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY) {
3045 if (--maxTrials == 0)
3046 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check bal ready failed");
3047 sleep(5);
3048 #ifdef TEST_MODE
3049 // It is impossible to mock the setting of olt_cfg.data.bal_state because
3050 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
3051 // set the olt_cfg.data.bal_state. So a new stub function is created and address
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04003052 // of olt_cfg is passed. This is one-of case where we need to add test specific
3053 // code in production code.
3054 if (bcmolt_cfg_get__bal_state_stub(dev_id, &olt_cfg)) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08003055 #else
3056 if (bcmolt_cfg_get(dev_id, &olt_cfg.hdr)) {
3057 #endif
3058 continue;
3059 }
3060 else
3061 OPENOLT_LOG(INFO, openolt_log_id, "waiting for BAL ready ...\n");
3062 }
3063
3064 OPENOLT_LOG(INFO, openolt_log_id, "BAL is ready\n");
3065 return Status::OK;
3066}