blob: 10d6c420135e68a63ef98affa739995b7e7389c3 [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());
2110 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2111 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
2112 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
2113
2114 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
2115 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2116 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002117 }
2118 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002119 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002120 }
2121
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002122 if (cfg.data.egress_intf.intf_type != BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002123 const ::openolt::ActionCmd& cmd = action.cmd();
2124
2125 if (cmd.add_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002126 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
2127 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002128 }
2129
2130 if (cmd.remove_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002131 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
2132 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002133 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002134 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002135 if (cmd.trap_to_host()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002136 OPENOLT_LOG(INFO, openolt_log_id, "action trap-to-host\n");
Craig Lutgen19512312018-11-02 10:14:46 -05002137 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002138 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002139 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002140 if (action.o_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002141 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002142 o_vid = action.o_vid();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002143 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002144 }
2145
2146 if (action.o_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002147 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
2148 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
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 (action.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002152 OPENOLT_LOG(INFO, openolt_log_id, "action o_tpid=0x%04x\n", action.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002153 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_tpid, action.o_tpid());
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.i_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002157 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
2158 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002159 }
2160
2161 if (action.i_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002162 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
2163 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002164 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002165 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002166 if (action.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002167 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_tpid=0x%04x\n", action.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002168 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_tpid, action.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002169 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002170 */
2171 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002172 }
2173
Shad Ansari39739bc2018-09-13 21:38:37 +00002174 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002175 if(single_tag && ether_type == EAP_ETHER_TYPE) {
2176 tm_val.sched_id = (flow_type.compare(upstream) == 0) ? \
2177 get_default_tm_sched_id(network_intf_id, upstream) : \
2178 get_default_tm_sched_id(access_intf_id, downstream);
2179 tm_val.queue_id = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002180
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002181 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2182 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2183 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002184
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002185 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2186 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2187 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2188 } else {
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002189 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002190 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
2191 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
2192
2193 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2194 // Queue 0 on DS subscriber scheduler
2195 tm_val.queue_id = 0;
2196
2197 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
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);
2200
2201 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2202 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2203 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2204
2205 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2206 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2207 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2208
2209 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2210 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2211 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2212 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2213
2214 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2215 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2216 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2217 }
2218 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2219 // NNI Scheduler ID
2220 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2221 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2222 // Queue 0 on NNI scheduler
2223 tm_val.queue_id = 0;
2224 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2225 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2226 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2227
2228 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2229 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2230 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2231
2232 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2233 /* Fetch TM QMP ID mapped to US NNI scheduler */
2234 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2235 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2236 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2237 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2238 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2239
2240 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2241 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2242 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2243 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002244 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002245 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302246 } else {
2247 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2248 tm_val.queue_id = 0;
2249
2250 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2251 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2252 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2253
2254 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2255 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2256 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002257 }
2258
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002259 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
2260 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2261#ifdef FLOW_CHECKER
2262 //Flow Checker, To avoid duplicate flow.
2263 if (flow_id_counters != 0) {
2264 bool b_duplicate_flow = false;
2265 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2266 int flow_index = flow_id_data[flowid][0];
2267 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)) && \
2268 (key.flow_type == flow_id_data[flowid][1]) && \
2269 (cfg.data.svc_port_id == get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)) && \
2270 (cfg.data.priority == get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)) && \
2271 (cfg.data.cookie == get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)) && \
2272 (cfg.data.ingress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE)) && \
2273 (cfg.data.ingress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)) && \
2274 (cfg.data.egress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)) && \
2275 (cfg.data.egress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)) && \
2276 (c_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)) && \
2277 (c_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)) && \
2278 (c_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)) && \
2279 (c_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)) && \
2280 (c_val.ether_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)) && \
2281 (c_val.ip_proto == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)) && \
2282 (c_val.src_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)) && \
2283 (c_val.dst_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)) && \
2284 (c_val.pkt_tag_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE)) && \
2285 (cfg.data.egress_qos.type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)) && \
2286 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)) && \
2287 (cfg.data.egress_qos.tm_sched.id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)) && \
2288 (a_val.cmds_bitmask == get_flow_status(flowid, flow_id_data[flowid][1], ACTION_CMDS_BITMASK)) && \
2289 (a_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)) && \
2290 (a_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)) && \
2291 (a_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)) && \
2292 (a_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)) && \
2293 (cfg.data.state == get_flow_status(flowid, flow_id_data[flowid][1], STATE));
2294#ifdef SHOW_FLOW_PARAM
2295 // Flow Parameter
2296 FLOW_PARAM_LOG();
2297#endif
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002298
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002299 if (b_duplicate_flow) {
2300 FLOW_LOG(WARNING, "Flow duplicate", 0);
2301 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2302 }
2303 }
2304 }
2305#endif
2306
2307 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2308 if (err) {
2309 FLOW_LOG(ERROR, "Flow add failed", err);
2310 return bcm_to_grpc_err(err, "flow add failed");
2311 } else {
2312 FLOW_LOG(INFO, "Flow add ok", err);
2313 bcmos_fastlock_lock(&data_lock);
2314 flow_id_data[flow_id_counters][0] = key.flow_id;
2315 flow_id_data[flow_id_counters][1] = key.flow_type;
2316 flow_id_counters += 1;
2317 bcmos_fastlock_unlock(&data_lock, 0);
2318 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002319
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002320 return Status::OK;
2321}
2322
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002323Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2324
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002325 bcmolt_flow_cfg cfg;
2326 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002327
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002328 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002329 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002330 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002331 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002332 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002333 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002334 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002335 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002336 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2337 }
2338
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002339 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002340 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002341 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002342 flowid_to_gemport.erase(key.flow_id);
2343 port_to_flows[port_no].erase(key.flow_id);
2344 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2345 }
2346 else
2347 {
2348 flowid_to_port.erase(key.flow_id);
2349 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002350 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002351
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002352 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002353
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002354 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002355 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002356 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 -04002357 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2358 }
2359
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002360 bcmos_fastlock_lock(&data_lock);
2361 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2362 if (flow_id_data[flowid][0] == flow_id && flow_id_data[flowid][1] == key.flow_type) {
2363 flow_id_counters -= 1;
2364 for (int i=flowid; i < flow_id_counters; i++) {
2365 flow_id_data[i][0] = flow_id_data[i + 1][0];
2366 flow_id_data[i][1] = flow_id_data[i + 1][1];
2367 }
2368 break;
2369 }
2370 }
2371 bcmos_fastlock_unlock(&data_lock, 0);
2372
2373 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002374 return Status::OK;
2375}
2376
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002377bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2378 bcmos_errno err;
2379 bcmolt_tm_sched_cfg tm_sched_cfg;
2380 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2381 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2382
Jason Huangbf45ffb2019-10-30 17:29:02 +08002383 //check TM scheduler has configured or not
2384 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2385 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
2386 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
2387 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002388 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 +08002389 return err;
2390 }
2391 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2392 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2393 return BCM_ERR_OK;
2394 }
2395
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002396 // bcmbal_tm_sched_owner
2397 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2398
2399 /**< The output of the tm_sched object instance */
2400 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2401
2402 if (direction.compare(upstream) == 0) {
2403 // In upstream it is NNI scheduler
2404 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2405 } else if (direction.compare(downstream) == 0) {
2406 // In downstream it is PON scheduler
2407 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2408 }
2409
2410 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2411
2412 // bcmbal_tm_sched_type
2413 // set the deafult policy to strict priority
2414 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2415
2416 // num_priorities: Max number of strict priority scheduling elements
2417 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
2418
2419 // bcmbal_tm_shaping
2420 uint32_t cir = 1000000;
2421 uint32_t pir = 1000000;
2422 uint32_t burst = 65536;
2423 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in %s pir=%u, burst=%u\n",
2424 direction.c_str(), pir, burst);
2425 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2426 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2427 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2428 // BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2429 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2430 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
2431
2432 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2433 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002434 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2435 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002436 return err;
2437 }
2438
2439 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2440 direction.c_str(), tm_sched_key.id, intf_id);
2441 return BCM_ERR_OK;
2442}
2443
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002444bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
2445 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2446 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002447
2448 bcmos_errno err;
2449
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002450 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002451 bcmolt_tm_sched_cfg tm_sched_cfg;
2452 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2453 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002454
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002455 // bcmbal_tm_sched_owner
2456 // In downstream it is sub_term scheduler
2457 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002458
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002459 /**< The output of the tm_sched object instance */
2460 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002461
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002462 // bcmbal_tm_sched_parent
2463 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2464 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2465 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_param.u.priority.priority, priority);
2466 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
2467 be achieved using the' virtual' type of attachment.
2468 tm_sched_owner.u.sub_term.intf_id = intf_id;
2469 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2470 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002471
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002472 // bcmbal_tm_sched_type
2473 // set the deafult policy to strict priority
2474 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002475
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002476 // num_priorities: Max number of strict priority scheduling elements
2477 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002478
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002479 // bcmbal_tm_shaping
2480 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2481 uint32_t cir = tf_sh_info.cir();
2482 uint32_t pir = tf_sh_info.pir();
2483 uint32_t burst = tf_sh_info.pbs();
2484 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2485 cir, pir, burst);
2486 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2487 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2488 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2489 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2490 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2491 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002492 }
2493
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002494 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002495 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002496 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002497intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2498port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002499 return err;
2500 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002501 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2502uni_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 -08002503
2504 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002505 bcmolt_itupon_alloc_cfg cfg;
2506 bcmolt_itupon_alloc_key key = { };
2507 key.pon_ni = intf_id;
2508 key.alloc_id = alloc_id;
2509 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
2510 int pir_bw = tf_sh_info.pir();
2511 int cir_bw = tf_sh_info.cir();
2512 //offset to match bandwidth granularity
2513 int offset_pir_bw = pir_bw%bw_granularity;
2514 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002515
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002516 pir_bw = pir_bw - offset_pir_bw;
2517 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002518
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002519 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002520
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002521 switch (additional_bw) {
2522 case 2: //AdditionalBW_BestEffort
2523 if (pir_bw == 0) {
2524 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2525%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2526 } else if (pir_bw < cir_bw) {
2527 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2528bandwidth (%d)\n", pir_bw, cir_bw);
2529 return BCM_ERR_PARM;
2530 } else if (pir_bw == cir_bw) {
2531 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2532bandwidth for additional bandwidth eligibility of type best_effort\n");
2533 return BCM_ERR_PARM;
2534 }
2535 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2536 break;
2537 case 1: //AdditionalBW_NA
2538 if (pir_bw == 0) {
2539 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2540%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2541 return BCM_ERR_PARM;
2542 } else if (cir_bw == 0) {
2543 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2544additional bandwidth eligibility of type Non-Assured (NA)\n");
2545 return BCM_ERR_PARM;
2546 } else if (pir_bw < cir_bw) {
2547 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2548bandwidth (%d)\n", pir_bw, cir_bw);
2549 return BCM_ERR_PARM;
2550 } else if (pir_bw == cir_bw) {
2551 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2552bandwidth for additional bandwidth eligibility of type non_assured\n");
2553 return BCM_ERR_PARM;
2554 }
2555 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2556 break;
2557 case 0: //AdditionalBW_None
2558 if (pir_bw == 0) {
2559 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
256016000 bytes/sec\n");
2561 return BCM_ERR_PARM;
2562 } else if (cir_bw == 0) {
2563 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2564for additional bandwidth eligibility of type None\n");
2565 return BCM_ERR_PARM;
2566 } else if (pir_bw > cir_bw) {
2567 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2568for additional bandwidth eligibility of type None\n");
2569 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2570bandwidth in None eligibility\n", pir_bw);
2571 cir_bw = pir_bw;
2572 } else if (pir_bw < cir_bw) {
2573 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2574bandwidth (%d)\n", pir_bw, cir_bw);
2575 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2576bandwidth in None eligibility\n", pir_bw);
2577 cir_bw = pir_bw;
2578 }
2579 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2580 break;
2581 default:
2582 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002583 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002584 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2585 in a fine granularity. */
2586 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2587 /* Fixed Bandwidth with no critical requirement of shaping */
2588 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2589 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2590 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2591 /* Maximum allocated bandwidth allowed for this alloc ID */
2592 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2593 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2594 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
2595 for skipped allocations during quiet window */
2596 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2597 /**< Allocation Profile index for CBR non-RT Bandwidth */
2598 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2599 /**< Allocation Profile index for CBR RT Bandwidth */
2600 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2601 /**< Alloc ID Weight used in case of Extended DBA mode */
2602 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2603 /**< Alloc ID Priority used in case of Extended DBA mode */
2604 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2605 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002606
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002607 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002608 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002609 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 -05002610port_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 -08002611 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002612 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002613 OPENOLT_LOG(INFO, openolt_log_id, "Create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d, port_no %u, \
2614alloc_id %d\n", intf_id,onu_id,uni_id,port_no,alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002615 }
2616
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002617 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002618}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002619
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002620Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2621 uint32_t intf_id = traffic_scheds->intf_id();
2622 uint32_t onu_id = traffic_scheds->onu_id();
2623 uint32_t uni_id = traffic_scheds->uni_id();
2624 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002625 std::string direction;
2626 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002627 tech_profile::SchedulerConfig sched_config;
2628 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002629 uint32_t priority;
2630 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002631 tech_profile::SchedulingPolicy sched_policy;
2632 tech_profile::TrafficShapingInfo traffic_shaping_info;
2633 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002634
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002635 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2636 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002637
2638 direction = GetDirection(traffic_sched.direction());
2639 if (direction.compare("direction-not-supported") == 0)
2640 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2641
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002642 alloc_id = traffic_sched.alloc_id();
2643 sched_config = traffic_sched.scheduler();
2644 additional_bw = sched_config.additional_bw();
2645 priority = sched_config.priority();
2646 weight = sched_config.weight();
2647 sched_policy = sched_config.sched_policy();
2648 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2649 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2650 sched_policy, traffic_shaping_info);
2651 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002652 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002653 return bcm_to_grpc_err(err, "Failed to create scheduler");
2654 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002655 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002656 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002657}
Jonathan Davis70c21812018-07-19 15:32:10 -04002658
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002659bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002660
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002661 bcmos_errno err;
Jonathan Davis70c21812018-07-19 15:32:10 -04002662
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002663 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002664 bcmolt_itupon_alloc_cfg cfg;
2665 bcmolt_itupon_alloc_key key = { };
2666 key.pon_ni = intf_id;
2667 key.alloc_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002668
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002669 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
2670 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2671 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002672 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2673 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002674 return err;
2675 }
2676 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, intf_id %d, alloc_id %d\n", \
2677 direction.c_str(), intf_id, alloc_id);
2678 } else if (direction == downstream) {
2679 bcmolt_tm_sched_cfg cfg;
2680 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002681
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002682 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
2683 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2684 } else {
2685 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2686 return BCM_ERR_OK;
2687 }
2688 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2689 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2690 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002691 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
2692intf_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 +00002693 return err;
2694 }
2695 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n", \
2696 direction.c_str(), key.id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002697 }
2698
2699 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002700 return BCM_ERR_OK;
2701}
2702
2703Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2704 uint32_t intf_id = traffic_scheds->intf_id();
2705 uint32_t onu_id = traffic_scheds->onu_id();
2706 uint32_t uni_id = traffic_scheds->uni_id();
2707 std::string direction;
2708 bcmos_errno err;
2709
2710 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2711 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002712
2713 direction = GetDirection(traffic_sched.direction());
2714 if (direction.compare("direction-not-supported") == 0)
2715 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2716
2717 int alloc_id = traffic_sched.alloc_id();
2718 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002719 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002720 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002721 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2722 }
2723 }
2724 return Status::OK;
2725}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002726
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002727bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2728 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002729 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002730 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2731 bcmolt_tm_qmp_key tm_qmp_key;
2732 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002733
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002734 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2735 if (tm_qmp_id == -1) {
2736 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 -08002737 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002738
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002739 tm_qmp_key.id = tm_qmp_id;
2740 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2741 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2742 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002743
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002744 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2745 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2746 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
2747 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2748 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002749
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002750 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002751 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002752 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2753 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002754 return err;
2755 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002756
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002757 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2758 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002759 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002760}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002761
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002762bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2763 bcmos_errno err;
2764 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2765 bcmolt_tm_qmp_key tm_qmp_key;
2766 tm_qmp_key.id = tm_qmp_id;
2767
2768 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2769 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2770 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002771 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2772 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002773 return err;
2774 }
2775
2776 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2777 tm_qmp_key.id);
2778 return BCM_ERR_OK;
2779}
2780
2781bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2782 bcmos_errno err;
2783
2784 /* Create 4 Queues on given PON/NNI scheduler */
2785 for (int queue_id = 0; queue_id < 4; queue_id++) {
2786 bcmolt_tm_queue_cfg tm_queue_cfg;
2787 bcmolt_tm_queue_key tm_queue_key = {};
2788 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2789 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002790 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2791 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2792 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002793
2794 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2795 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2796 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2797
2798 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2799 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002800 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", \
2801 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 +00002802 return err;
2803 }
2804
2805 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2806 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2807 }
2808 return BCM_ERR_OK;
2809}
2810
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002811bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2812 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002813 bcmos_errno err;
2814 bcmolt_tm_queue_cfg cfg;
2815 bcmolt_tm_queue_key key = { };
2816 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
2817gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
2818
2819 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2820 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2821
2822 if (priority > 7) {
2823 return BCM_ERR_RANGE;
2824 }
2825
2826 /* FIXME: The upstream queues have to be created once only.
2827 The upstream queues on the NNI scheduler are shared by all subscribers.
2828 When the first scheduler comes in, the queues get created, and are re-used by all others.
2829 Also, these queues should be present until the last subscriber exits the system.
2830 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2831
2832 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2833 for each GEM in TECH PROFILE */
2834 key.id = queue_id_list[priority];
2835
2836 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2837 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2838 key.id = 0;
2839 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2840 }
2841 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2842 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2843 }
2844 else {
2845 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2846 }
2847
2848 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2849
2850 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2851 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2852
2853 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2854 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002855 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
2856sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n", \
2857 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 +00002858 return err;
2859 }
2860
2861 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2862intf_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);
2863 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002864}
2865
2866Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2867 uint32_t intf_id = traffic_queues->intf_id();
2868 uint32_t onu_id = traffic_queues->onu_id();
2869 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002870 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002871 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002872 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002873 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 +00002874
2875 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2876 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2877 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2878 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2879 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2880
2881 direction = GetDirection(traffic_queue.direction());
2882 if (direction.compare("direction-not-supported") == 0)
2883 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2884
2885 queues_priority_q[i] = traffic_queue.priority();
2886 queues_pbit_map[i] = traffic_queue.pbit_map();
2887 }
2888
2889 std::vector<uint32_t> tmq_map_profile(8, 0);
2890 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2891 queues_priority_q, COUNT_OF(queues_priority_q));
2892 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2893 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2894
2895 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2896 if (tm_qmp_id == -1) {
2897 CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2898 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2899 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2900 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2901 }
2902 }
2903
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002904 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2905 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002906
2907 direction = GetDirection(traffic_queue.direction());
2908 if (direction.compare("direction-not-supported") == 0)
2909 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2910
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002911 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 +00002912
Girish Gowdruf26cf882019-05-01 23:47:58 -07002913 // If the queue exists already, lets not return failure and break the loop.
2914 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002915 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002916 return bcm_to_grpc_err(err, "Failed to create queue");
2917 }
2918 }
2919 return Status::OK;
2920}
2921
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002922bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2923 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002924 bcmolt_tm_queue_cfg cfg;
2925 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002926 bcmos_errno err;
2927
2928 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002929 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
2930 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2931 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002932 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002933 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 -08002934 return BCM_ERR_OK;
2935 }
2936 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002937 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2938 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002939 return BCM_ERR_OK;
2940 }
2941
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002942 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2943 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2944 // Reset the queue id to 0 when using fixed queue.
2945 key.id = 0;
2946 }
2947 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2948 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2949 }
2950 else {
2951 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2952 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002953
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002954 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2955 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002956 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002957 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2958tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2959 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 -08002960 return err;
2961 }
2962
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002963 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2964intf_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 -08002965
2966 return BCM_ERR_OK;
2967}
2968
2969Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2970 uint32_t intf_id = traffic_queues->intf_id();
2971 uint32_t onu_id = traffic_queues->onu_id();
2972 uint32_t uni_id = traffic_queues->uni_id();
2973 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002974 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002975 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002976 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002977 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 +00002978
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002979 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2980 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002981
2982 direction = GetDirection(traffic_queue.direction());
2983 if (direction.compare("direction-not-supported") == 0)
2984 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2985
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002986 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 -08002987 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002988 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002989 return bcm_to_grpc_err(err, "Failed to remove queue");
2990 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002991 }
2992
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002993 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))) {
2994 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2995 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2996
2997 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2998 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
2999 RemoveTrafficQueueMappingProfile(tm_qmp_id);
3000 }
3001 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003002 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04003003 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04003004}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003005
3006Status check_connection() {
3007 int maxTrials = 60;
3008 while (!bcmolt_api_conn_mgr_is_connected(dev_id)) {
3009 sleep(1);
3010 if (--maxTrials == 0)
3011 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check connection failed");
3012 else
3013 OPENOLT_LOG(INFO, openolt_log_id, "waiting for daemon connection ...\n");
3014 }
3015 OPENOLT_LOG(INFO, openolt_log_id, "daemon is connected\n");
3016 return Status::OK;
3017}
3018
3019Status check_bal_ready() {
3020 bcmos_errno err;
3021 int maxTrials = 30;
3022 bcmolt_olt_cfg olt_cfg = { };
3023 bcmolt_olt_key olt_key = { };
3024
3025 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
3026 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
3027
3028 while (olt_cfg.data.bal_state != BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY) {
3029 if (--maxTrials == 0)
3030 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check bal ready failed");
3031 sleep(5);
3032 #ifdef TEST_MODE
3033 // It is impossible to mock the setting of olt_cfg.data.bal_state because
3034 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
3035 // set the olt_cfg.data.bal_state. So a new stub function is created and address
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04003036 // of olt_cfg is passed. This is one-of case where we need to add test specific
3037 // code in production code.
3038 if (bcmolt_cfg_get__bal_state_stub(dev_id, &olt_cfg)) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08003039 #else
3040 if (bcmolt_cfg_get(dev_id, &olt_cfg.hdr)) {
3041 #endif
3042 continue;
3043 }
3044 else
3045 OPENOLT_LOG(INFO, openolt_log_id, "waiting for BAL ready ...\n");
3046 }
3047
3048 OPENOLT_LOG(INFO, openolt_log_id, "BAL is ready\n");
3049 return Status::OK;
3050}