blob: 148ae087164070229e49de05c5c2d0e27b73fb58 [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) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001552 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001553 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001554 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1555 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001556
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001557 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1558 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1559 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1560
1561 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1562 if (err != BCM_ERR_OK) {
1563 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1564 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1565 }
1566
1567 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1568 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1569
1570 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1571 if (err != BCM_ERR_OK) {
1572 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n , err %d\n", intf_id, err);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001573 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001574 }
1575
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001576 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001577 return Status::OK;
1578}
1579
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001580Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001581 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001582 bcmos_errno err = BCM_ERR_OK;
1583 bcmolt_onu_cfg onu_cfg;
1584 bcmolt_onu_key onu_key;
1585 bcmolt_serial_number serial_number; /**< ONU serial number */
1586 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001587
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001588 onu_key.onu_id = onu_id;
1589 onu_key.pon_ni = intf_id;
1590 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1591 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1592 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001593 if (err == BCM_ERR_OK) {
1594 if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING ||
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001595 onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) ||
1596 (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_INACTIVE &&
1597 onu_cfg.data.onu_old_state == BCMOLT_ONU_STATE_NOT_CONFIGURED))
1598 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001599 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001600
1601 OPENOLT_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001602vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001603 vendor_specific_to_str(vendor_specific).c_str(), pir);
1604
1605 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1606 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1607 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1608 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1609 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1610 /*set burst and data profiles to fec disabled*/
1611 if (board_technology == "XGS-PON") {
1612 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1613 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1614 } else if (board_technology == "GPON") {
1615 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1616 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1617 }
1618 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1619 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001620 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 +00001621 return bcm_to_grpc_err(err, "Failed to activate ONU");
1622 }
1623
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001624 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001625}
1626
Jonathan Davis70c21812018-07-19 15:32:10 -04001627Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1628 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001629 bcmos_errno err = BCM_ERR_OK;
1630 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1631 bcmolt_onu_cfg onu_cfg;
1632 bcmolt_onu_key onu_key; /**< Object key. */
1633 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001634
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001635 onu_key.onu_id = onu_id;
1636 onu_key.pon_ni = intf_id;
1637 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1638 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1639 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001640 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001641 switch (onu_state) {
1642 case BCMOLT_ONU_OPERATION_ACTIVE:
1643 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001644 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001645 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1646 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1647 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001648 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 +00001649 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1650 }
1651 break;
1652 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001653 }
1654
1655 return Status::OK;
1656}
1657
1658Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001659 const char *vendor_id, const char *vendor_specific) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001660
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001661 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 -05001662 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1663
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001664 // Need to deactivate before removing it (BAL rules)
1665
1666 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1667 // Sleep to allow the state to propagate
1668 // We need the subscriber terminal object to be admin down before removal
1669 // Without sleep the race condition is lost by ~ 20 ms
1670 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1671
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001672 // TODO: Delete the schedulers and queues.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001673
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001674 bcmolt_onu_cfg cfg_obj;
1675 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001676
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001677 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 -04001678 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001679
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001680 key.onu_id = onu_id;
1681 key.pon_ni = intf_id;
1682 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001683
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001684 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001685 if (err != BCM_ERR_OK)
1686 {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001687 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 -04001688 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1689 }
1690
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001691 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001692}
1693
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001694#define MAX_CHAR_LENGTH 20
1695#define MAX_OMCI_MSG_LENGTH 44
1696Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001697 bcmolt_bin_str buf = {};
1698 bcmolt_onu_cpu_packets omci_cpu_packets;
1699 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001700
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001701 key.pon_ni = intf_id;
1702 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001703
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001704 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1705 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1706 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001707
1708 // ???
1709 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1710 buf.len = MAX_OMCI_MSG_LENGTH;
1711 } else {
1712 buf.len = pkt.size()/2;
1713 }
1714
1715 /* Send the OMCI packet using the BAL remote proxy API */
1716 uint16_t idx1 = 0;
1717 uint16_t idx2 = 0;
1718 uint8_t arraySend[buf.len];
1719 char str1[MAX_CHAR_LENGTH];
1720 char str2[MAX_CHAR_LENGTH];
1721 memset(&arraySend, 0, buf.len);
1722
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001723 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1724 sprintf(str1,"%c", pkt[idx1]);
1725 sprintf(str2,"%c", pkt[++idx1]);
1726 strcat(str1,str2);
1727 arraySend[idx2] = strtol(str1, NULL, 16);
1728 }
1729
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001730 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1731 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001732
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001733 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1734 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1735 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001736
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001737 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001738 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001739 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 +00001740 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001741 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001742 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 -05001743 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001744 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001745 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001746
1747 return Status::OK;
1748}
1749
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001750Status 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 +00001751 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1752 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1753 bcmolt_bin_str buf = {};
1754 bcmolt_gem_port_id gem_port_id_array[1];
1755 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001756
Craig Lutgen967a1d02018-11-27 10:41:51 -06001757 if (port_no > 0) {
1758 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001759 if (gemport_id == 0) {
1760 bcmos_fastlock_lock(&data_lock);
1761 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1762 // Pick any flow that is mapped with the same port_no.
1763 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1764 if (it != port_to_flows.end() && !it->second.empty()) {
1765 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1766 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1767 if (fit != flowid_to_gemport.end()) {
1768 found = true;
1769 gemport_id = fit->second;
1770 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001771 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001772 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001773
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001774 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001775 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 -08001776 onu_id, port_no, intf_id);
1777 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1778 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001779 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 -08001780 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001781 }
1782
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001783 gem_port_id_array[0] = gemport_id;
1784 gem_port_list.len = 1;
1785 gem_port_list.arr = gem_port_id_array;
1786 buf.len = pkt.size();
1787 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1788 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1789
1790 /* init the API struct */
1791 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1792 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1793 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1794 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1795 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1796
1797 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1798 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1799
1800 /* call API */
1801 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001802 }
1803 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001804 //TODO: Port No is 0, it is coming sender requirement.
1805 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1806 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001807 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001808 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001809
1810 return Status::OK;
1811}
1812
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001813Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001814 bcmolt_flow_key key = {}; /* declare key */
1815 bcmolt_bin_str buffer = {};
1816 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001817
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001818 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1819 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001820
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001821 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1822 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1823 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1824 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1825 key.flow_id = flow_id;
1826 else {
1827 if (flow_id_counters != 0) {
1828 for (int flowid=0; flowid < flow_id_counters; flowid++) {
1829 int flow_index = flow_id_data[flowid][0];
1830 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1831 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1832 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1833 key.flow_id = flow_index;
1834 break;
1835 }
1836 }
1837 }
1838 else {
1839 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1840 }
1841 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001842
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001843 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001844
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001845 /* Initialize the API struct. */
1846 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001847
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001848 buffer.len = pkt.size();
1849 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1850 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1851 if (buffer.arr == NULL) {
1852 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1853 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1854 }
1855 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1856
1857 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1858 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001859 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 +00001860 } else {
1861 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1862 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001863
1864 return Status::OK;
1865}
1866
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001867uint32_t GetPortNum_(uint32_t flow_id) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001868 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001869 uint32_t port_no = 0;
1870 std::map<uint32_t, uint32_t >::const_iterator it = flowid_to_port.find(flow_id);
1871 if (it != flowid_to_port.end()) {
1872 port_no = it->second;
1873 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001874 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001875 return port_no;
1876}
1877
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001878#define FLOW_LOG(level,msg,err) \
1879 do { \
1880 OPENOLT_LOG(level, openolt_log_id, "--------> %s (flow_id %d) err: %d <--------\n", msg, key.flow_id, err); \
1881 OPENOLT_LOG(level, openolt_log_id, "intf_id %d, onu_id %d, uni_id %d, port_no %u, cookie %"PRIu64"\n", \
1882 access_intf_id, onu_id, uni_id, port_no, cookie); \
1883 OPENOLT_LOG(level, openolt_log_id, "flow_type %s, queue_id %d, sched_id %d\n", flow_type.c_str(), \
1884 cfg.data.egress_qos.u.fixed_queue.queue_id, cfg.data.egress_qos.tm_sched.id); \
1885 OPENOLT_LOG(level, openolt_log_id, "Ingress(intfd_type %s, intf_id %d), Egress(intf_type %s, intf_id %d)\n", \
1886 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), cfg.data.ingress_intf.intf_id, \
1887 GET_FLOW_INTERFACE_TYPE(cfg.data.egress_intf.intf_type), cfg.data.egress_intf.intf_id); \
1888 OPENOLT_LOG(level, openolt_log_id, "classifier(o_vid %d, o_pbits %d, i_vid %d, i_pbits %d, ether type 0x%x)\n", \
1889 c_val.o_vid, c_val.o_pbits, c_val.i_vid, c_val.i_pbits, classifier.eth_type()); \
1890 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", \
1891 c_val.ip_proto, gemport_id, c_val.src_port, c_val.dst_port, GET_PKT_TAG_TYPE(c_val.pkt_tag_type)); \
1892 OPENOLT_LOG(level, openolt_log_id, "action(cmds_bitmask %s, o_vid %d, o_pbits %d, i_vid %d, i_pbits %d)\n\n", \
1893 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 -04001894 } while(0)
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001895
1896#define FLOW_PARAM_LOG() \
1897 do { \
1898 OPENOLT_LOG(INFO, openolt_log_id, "--------> flow comparison (now before) <--------\n"); \
1899 OPENOLT_LOG(INFO, openolt_log_id, "flow_id (%d %d)\n", \
1900 key.flow_id, flow_index); \
1901 OPENOLT_LOG(INFO, openolt_log_id, "onu_id (%d %lu)\n", \
1902 cfg.data.onu_id , get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)); \
1903 OPENOLT_LOG(INFO, openolt_log_id, "type (%d %lu)\n", \
1904 key.flow_type, get_flow_status(flow_index, flow_id_data[flowid][1], FLOW_TYPE)); \
1905 OPENOLT_LOG(INFO, openolt_log_id, "svc_port_id (%d %lu)\n", \
1906 cfg.data.svc_port_id, get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)); \
1907 OPENOLT_LOG(INFO, openolt_log_id, "priority (%d %lu)\n", \
1908 cfg.data.priority, get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)); \
1909 OPENOLT_LOG(INFO, openolt_log_id, "cookie (%lu %lu)\n", \
1910 cfg.data.cookie, get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)); \
1911 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf_type (%s %s)\n", \
1912 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), \
1913 GET_FLOW_INTERFACE_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE))); \
1914 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf id (%d %lu)\n", \
1915 cfg.data.ingress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)); \
1916 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_type (%d %lu)\n", \
1917 cfg.data.egress_intf.intf_type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)); \
1918 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_id (%d %lu)\n", \
1919 cfg.data.egress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)); \
1920 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_vid (%d %lu)\n", \
1921 c_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)); \
1922 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_pbits (%d %lu)\n", \
1923 c_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)); \
1924 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_vid (%d %lu)\n", \
1925 c_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)); \
1926 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_pbits (%d %lu)\n", \
1927 c_val.i_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)); \
1928 OPENOLT_LOG(INFO, openolt_log_id, "classifier ether_type (0x%x 0x%lx)\n", \
1929 c_val.ether_type , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)); \
1930 OPENOLT_LOG(INFO, openolt_log_id, "classifier ip_proto (%d %lu)\n", \
1931 c_val.ip_proto , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)); \
1932 OPENOLT_LOG(INFO, openolt_log_id, "classifier src_port (%d %lu)\n", \
1933 c_val.src_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)); \
1934 OPENOLT_LOG(INFO, openolt_log_id, "classifier dst_port (%d %lu)\n", \
1935 c_val.dst_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)); \
1936 OPENOLT_LOG(INFO, openolt_log_id, "classifier pkt_tag_type (%s %s)\n", \
1937 GET_PKT_TAG_TYPE(c_val.pkt_tag_type), \
1938 GET_PKT_TAG_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE))); \
1939 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos type (%d %lu)\n", \
1940 cfg.data.egress_qos.type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)); \
1941 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos queue_id (%d %lu)\n", \
1942 cfg.data.egress_qos.u.fixed_queue.queue_id, \
1943 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)); \
1944 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos sched_id (%d %lu)\n", \
1945 cfg.data.egress_qos.tm_sched.id, \
1946 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)); \
1947 OPENOLT_LOG(INFO, openolt_log_id, "classifier cmds_bitmask (%s %s)\n", \
1948 get_flow_acton_command(a_val.cmds_bitmask), \
1949 get_flow_acton_command(get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_CMDS_BITMASK))); \
1950 OPENOLT_LOG(INFO, openolt_log_id, "action o_vid (%d %lu)\n", \
1951 a_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)); \
1952 OPENOLT_LOG(INFO, openolt_log_id, "action i_vid (%d %lu)\n", \
1953 a_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)); \
1954 OPENOLT_LOG(INFO, openolt_log_id, "action o_pbits (%d %lu)\n", \
1955 a_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)); \
1956 OPENOLT_LOG(INFO, openolt_log_id, "action i_pbits (%d %lu)\n\n", \
1957 a_val.i_pbits, get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)); \
1958 } while(0)
1959
1960#define FLOW_CHECKER
1961//#define SHOW_FLOW_PARAM
1962
Craig Lutgen967a1d02018-11-27 10:41:51 -06001963Status 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 +00001964 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001965 int32_t alloc_id, int32_t network_intf_id,
1966 int32_t gemport_id, const ::openolt::Classifier& classifier,
Craig Lutgen967a1d02018-11-27 10:41:51 -06001967 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001968 bcmolt_flow_cfg cfg;
1969 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001970 int32_t o_vid = -1;
1971 bool single_tag = false;
1972 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001973 bcmolt_classifier c_val = { };
1974 bcmolt_action a_val = { };
1975 bcmolt_tm_queue_ref tm_val = { };
1976 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001977 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001978
1979 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001980 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001981 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001982 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001983 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001984 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001985 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001986 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001987 }
1988
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001989 BCMOLT_CFG_INIT(&cfg, flow, key);
1990 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001991
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001992 if (access_intf_id >= 0 && network_intf_id >= 0) {
1993 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1994 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1995 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
1996 if (classifier.eth_type() == EAP_ETHER_TYPE || //EAPOL packet
1997 (classifier.ip_proto() == 17 && classifier.src_port() == 68 && classifier.dst_port() == 67)) { //DHCP packet
1998 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
1999 } else {
2000 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2001 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
2002 }
2003 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
2004 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2005 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
2006 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
2007 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
2008 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302009 } else if (access_intf_id < 0 ) {
2010 // This is the case for packet trap from NNI flow.
2011 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2012 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
2013 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002014 } else {
2015 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
2016 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
2017 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002018
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302019
Shad Ansari39739bc2018-09-13 21:38:37 +00002020 if (onu_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002021 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00002022 }
2023 if (gemport_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002024 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00002025 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002026 if (gemport_id >= 0 && port_no != 0) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002027 bcmos_fastlock_lock(&data_lock);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002028 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002029 port_to_flows[port_no].insert(key.flow_id);
2030 flowid_to_gemport[key.flow_id] = gemport_id;
2031 }
2032 else
2033 {
2034 flowid_to_port[key.flow_id] = port_no;
2035 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002036 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002037 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002038 if (priority_value >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002039 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
Shad Ansari39739bc2018-09-13 21:38:37 +00002040 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002041
2042 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002043 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002044 if (classifier.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002045 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_tpid 0x%04x\n", classifier.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002046 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_tpid, classifier.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002047 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002048 */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002049 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002050 if (classifier.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002051 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_tpid 0x%04x\n", classifier.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002052 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_tpid, classifier.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002053 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002054 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002055
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002056 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002057 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002058 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
2059 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002060 }
2061
2062 /*
2063 if (classifier.dst_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002064 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_mac, classifier.dst_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002065 }
2066
2067 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002068 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002069 }
2070 */
2071
2072 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002073 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
2074 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002075 }
2076
2077 /*
2078 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002079 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002080 }
2081
2082 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002083 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002084 }
2085 */
2086
2087 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002088 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
2089 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002090 }
2091
2092 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002093 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
2094 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002095 }
2096
2097 if (!classifier.pkt_tag_type().empty()) {
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302098 if (cfg.data.ingress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_NNI && \
2099 cfg.data.egress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
2100 // This is case where packet traps from NNI port. As per Broadcom workaround
2101 // suggested in CS8839882, the packet_tag_type has to be 'untagged' irrespective
2102 // of what the actual tag type is. Otherwise, packet trap from NNI wont work.
2103 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2104 } else {
2105 if (classifier.o_vid()) {
2106 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
2107 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
2108 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002109
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302110 if (classifier.i_vid()) {
2111 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
2112 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
2113 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002114
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302115 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
2116 if (classifier.pkt_tag_type().compare("untagged") == 0) {
2117 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2118 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
2119 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
2120 single_tag = true;
2121
2122 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
YJbbeeff42019-11-21 16:22:50 -05002123 if(classifier.o_pbits()){
2124 //According to makeOpenOltClassifierField in voltha-openolt-adapter, o_pbits 0xFF means PCP value 0.
2125 //0 vlaue of o_pbits means o_pbits is not available
2126 if(0xFF == classifier.o_pbits()){
2127 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, 0);
2128 }
2129 else{
2130 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2131 }
2132 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302133 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
2134 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
2135
2136 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
YJbbeeff42019-11-21 16:22:50 -05002137 if(classifier.o_pbits()){
2138 if(0xFF == classifier.o_pbits()){
2139 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, 0);
2140 }
2141 else{
2142 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2143 }
2144 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302145 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002146 }
2147 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002148 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002149 }
2150
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002151 if (cfg.data.egress_intf.intf_type != BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002152 const ::openolt::ActionCmd& cmd = action.cmd();
2153
2154 if (cmd.add_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002155 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
2156 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002157 }
2158
2159 if (cmd.remove_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002160 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
2161 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002162 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002163 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002164 if (cmd.trap_to_host()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002165 OPENOLT_LOG(INFO, openolt_log_id, "action trap-to-host\n");
Craig Lutgen19512312018-11-02 10:14:46 -05002166 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002167 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002168 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002169 if (action.o_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002170 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002171 o_vid = action.o_vid();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002172 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002173 }
2174
2175 if (action.o_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002176 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
2177 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002178 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002179 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002180 if (action.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002181 OPENOLT_LOG(INFO, openolt_log_id, "action o_tpid=0x%04x\n", action.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002182 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_tpid, action.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002183 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002184 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002185 if (action.i_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002186 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
2187 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002188 }
2189
2190 if (action.i_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002191 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
2192 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002193 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002194 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002195 if (action.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002196 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_tpid=0x%04x\n", action.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002197 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_tpid, action.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002198 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002199 */
2200 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002201 }
2202
Shad Ansari39739bc2018-09-13 21:38:37 +00002203 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002204 if(single_tag && ether_type == EAP_ETHER_TYPE) {
2205 tm_val.sched_id = (flow_type.compare(upstream) == 0) ? \
2206 get_default_tm_sched_id(network_intf_id, upstream) : \
2207 get_default_tm_sched_id(access_intf_id, downstream);
2208 tm_val.queue_id = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002209
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002210 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2211 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2212 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002213
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002214 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2215 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2216 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2217 } else {
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002218 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002219 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
2220 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
2221
2222 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2223 // Queue 0 on DS subscriber scheduler
2224 tm_val.queue_id = 0;
2225
2226 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2227 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2228 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2229
2230 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2231 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2232 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2233
2234 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2235 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2236 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2237
2238 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2239 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2240 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2241 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2242
2243 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2244 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2245 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2246 }
2247 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2248 // NNI Scheduler ID
2249 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2250 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2251 // Queue 0 on NNI scheduler
2252 tm_val.queue_id = 0;
2253 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2254 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2255 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2256
2257 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2258 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2259 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2260
2261 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2262 /* Fetch TM QMP ID mapped to US NNI scheduler */
2263 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2264 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2265 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2266 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2267 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2268
2269 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2270 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2271 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2272 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002273 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002274 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302275 } else {
2276 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2277 tm_val.queue_id = 0;
2278
2279 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2280 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2281 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2282
2283 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2284 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2285 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002286 }
2287
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002288 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
2289 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2290#ifdef FLOW_CHECKER
2291 //Flow Checker, To avoid duplicate flow.
2292 if (flow_id_counters != 0) {
2293 bool b_duplicate_flow = false;
2294 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2295 int flow_index = flow_id_data[flowid][0];
2296 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)) && \
2297 (key.flow_type == flow_id_data[flowid][1]) && \
2298 (cfg.data.svc_port_id == get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)) && \
2299 (cfg.data.priority == get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)) && \
2300 (cfg.data.cookie == get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)) && \
2301 (cfg.data.ingress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE)) && \
2302 (cfg.data.ingress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)) && \
2303 (cfg.data.egress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)) && \
2304 (cfg.data.egress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)) && \
2305 (c_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)) && \
2306 (c_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)) && \
2307 (c_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)) && \
2308 (c_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)) && \
2309 (c_val.ether_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)) && \
2310 (c_val.ip_proto == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)) && \
2311 (c_val.src_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)) && \
2312 (c_val.dst_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)) && \
2313 (c_val.pkt_tag_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE)) && \
2314 (cfg.data.egress_qos.type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)) && \
2315 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)) && \
2316 (cfg.data.egress_qos.tm_sched.id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)) && \
2317 (a_val.cmds_bitmask == get_flow_status(flowid, flow_id_data[flowid][1], ACTION_CMDS_BITMASK)) && \
2318 (a_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)) && \
2319 (a_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)) && \
2320 (a_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)) && \
2321 (a_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)) && \
2322 (cfg.data.state == get_flow_status(flowid, flow_id_data[flowid][1], STATE));
2323#ifdef SHOW_FLOW_PARAM
2324 // Flow Parameter
2325 FLOW_PARAM_LOG();
2326#endif
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002327
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002328 if (b_duplicate_flow) {
2329 FLOW_LOG(WARNING, "Flow duplicate", 0);
2330 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2331 }
2332 }
2333 }
2334#endif
2335
2336 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2337 if (err) {
2338 FLOW_LOG(ERROR, "Flow add failed", err);
2339 return bcm_to_grpc_err(err, "flow add failed");
2340 } else {
2341 FLOW_LOG(INFO, "Flow add ok", err);
2342 bcmos_fastlock_lock(&data_lock);
2343 flow_id_data[flow_id_counters][0] = key.flow_id;
2344 flow_id_data[flow_id_counters][1] = key.flow_type;
2345 flow_id_counters += 1;
2346 bcmos_fastlock_unlock(&data_lock, 0);
2347 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002348
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002349 return Status::OK;
2350}
2351
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002352Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2353
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002354 bcmolt_flow_cfg cfg;
2355 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002356
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002357 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002358 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002359 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002360 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002361 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002362 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002363 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002364 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002365 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2366 }
2367
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002368 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002369 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002370 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002371 flowid_to_gemport.erase(key.flow_id);
2372 port_to_flows[port_no].erase(key.flow_id);
2373 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2374 }
2375 else
2376 {
2377 flowid_to_port.erase(key.flow_id);
2378 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002379 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002380
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002381 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002382
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002383 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002384 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002385 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 -04002386 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2387 }
2388
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002389 bcmos_fastlock_lock(&data_lock);
2390 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2391 if (flow_id_data[flowid][0] == flow_id && flow_id_data[flowid][1] == key.flow_type) {
2392 flow_id_counters -= 1;
2393 for (int i=flowid; i < flow_id_counters; i++) {
2394 flow_id_data[i][0] = flow_id_data[i + 1][0];
2395 flow_id_data[i][1] = flow_id_data[i + 1][1];
2396 }
2397 break;
2398 }
2399 }
2400 bcmos_fastlock_unlock(&data_lock, 0);
2401
2402 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002403 return Status::OK;
2404}
2405
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002406bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2407 bcmos_errno err;
2408 bcmolt_tm_sched_cfg tm_sched_cfg;
2409 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2410 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2411
Jason Huangbf45ffb2019-10-30 17:29:02 +08002412 //check TM scheduler has configured or not
2413 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2414 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
2415 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
2416 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002417 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 +08002418 return err;
2419 }
2420 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2421 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2422 return BCM_ERR_OK;
2423 }
2424
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002425 // bcmbal_tm_sched_owner
2426 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2427
2428 /**< The output of the tm_sched object instance */
2429 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2430
2431 if (direction.compare(upstream) == 0) {
2432 // In upstream it is NNI scheduler
2433 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2434 } else if (direction.compare(downstream) == 0) {
2435 // In downstream it is PON scheduler
2436 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2437 }
2438
2439 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2440
2441 // bcmbal_tm_sched_type
2442 // set the deafult policy to strict priority
2443 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2444
2445 // num_priorities: Max number of strict priority scheduling elements
2446 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
2447
2448 // bcmbal_tm_shaping
2449 uint32_t cir = 1000000;
2450 uint32_t pir = 1000000;
2451 uint32_t burst = 65536;
2452 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in %s pir=%u, burst=%u\n",
2453 direction.c_str(), pir, burst);
2454 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2455 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2456 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2457 // BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2458 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2459 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
2460
2461 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2462 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002463 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2464 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002465 return err;
2466 }
2467
2468 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2469 direction.c_str(), tm_sched_key.id, intf_id);
2470 return BCM_ERR_OK;
2471}
2472
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002473bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
2474 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2475 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002476
2477 bcmos_errno err;
2478
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002479 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002480 bcmolt_tm_sched_cfg tm_sched_cfg;
2481 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2482 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002483
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002484 // bcmbal_tm_sched_owner
2485 // In downstream it is sub_term scheduler
2486 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002487
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002488 /**< The output of the tm_sched object instance */
2489 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002490
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002491 // bcmbal_tm_sched_parent
2492 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2493 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2494 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_param.u.priority.priority, priority);
2495 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
2496 be achieved using the' virtual' type of attachment.
2497 tm_sched_owner.u.sub_term.intf_id = intf_id;
2498 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2499 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002500
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002501 // bcmbal_tm_sched_type
2502 // set the deafult policy to strict priority
2503 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002504
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002505 // num_priorities: Max number of strict priority scheduling elements
2506 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002507
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002508 // bcmbal_tm_shaping
2509 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2510 uint32_t cir = tf_sh_info.cir();
2511 uint32_t pir = tf_sh_info.pir();
2512 uint32_t burst = tf_sh_info.pbs();
2513 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2514 cir, pir, burst);
2515 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2516 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2517 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2518 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2519 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2520 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002521 }
2522
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002523 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002524 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002525 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002526intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2527port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002528 return err;
2529 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002530 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2531uni_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 -08002532
2533 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002534 bcmolt_itupon_alloc_cfg cfg;
2535 bcmolt_itupon_alloc_key key = { };
2536 key.pon_ni = intf_id;
2537 key.alloc_id = alloc_id;
2538 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
2539 int pir_bw = tf_sh_info.pir();
2540 int cir_bw = tf_sh_info.cir();
2541 //offset to match bandwidth granularity
2542 int offset_pir_bw = pir_bw%bw_granularity;
2543 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002544
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002545 pir_bw = pir_bw - offset_pir_bw;
2546 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002547
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002548 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002549
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002550 switch (additional_bw) {
2551 case 2: //AdditionalBW_BestEffort
2552 if (pir_bw == 0) {
2553 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2554%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2555 } else if (pir_bw < cir_bw) {
2556 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2557bandwidth (%d)\n", pir_bw, cir_bw);
2558 return BCM_ERR_PARM;
2559 } else if (pir_bw == cir_bw) {
2560 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2561bandwidth for additional bandwidth eligibility of type best_effort\n");
2562 return BCM_ERR_PARM;
2563 }
2564 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2565 break;
2566 case 1: //AdditionalBW_NA
2567 if (pir_bw == 0) {
2568 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2569%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2570 return BCM_ERR_PARM;
2571 } else if (cir_bw == 0) {
2572 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2573additional bandwidth eligibility of type Non-Assured (NA)\n");
2574 return BCM_ERR_PARM;
2575 } else if (pir_bw < cir_bw) {
2576 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2577bandwidth (%d)\n", pir_bw, cir_bw);
2578 return BCM_ERR_PARM;
2579 } else if (pir_bw == cir_bw) {
2580 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2581bandwidth for additional bandwidth eligibility of type non_assured\n");
2582 return BCM_ERR_PARM;
2583 }
2584 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2585 break;
2586 case 0: //AdditionalBW_None
2587 if (pir_bw == 0) {
2588 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
258916000 bytes/sec\n");
2590 return BCM_ERR_PARM;
2591 } else if (cir_bw == 0) {
2592 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2593for additional bandwidth eligibility of type None\n");
2594 return BCM_ERR_PARM;
2595 } else if (pir_bw > cir_bw) {
2596 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2597for additional bandwidth eligibility of type None\n");
2598 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2599bandwidth in None eligibility\n", pir_bw);
2600 cir_bw = pir_bw;
2601 } else if (pir_bw < cir_bw) {
2602 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2603bandwidth (%d)\n", pir_bw, cir_bw);
2604 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2605bandwidth in None eligibility\n", pir_bw);
2606 cir_bw = pir_bw;
2607 }
2608 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2609 break;
2610 default:
2611 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002612 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002613 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2614 in a fine granularity. */
2615 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2616 /* Fixed Bandwidth with no critical requirement of shaping */
2617 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2618 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2619 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2620 /* Maximum allocated bandwidth allowed for this alloc ID */
2621 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2622 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2623 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
2624 for skipped allocations during quiet window */
2625 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2626 /**< Allocation Profile index for CBR non-RT Bandwidth */
2627 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2628 /**< Allocation Profile index for CBR RT Bandwidth */
2629 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2630 /**< Alloc ID Weight used in case of Extended DBA mode */
2631 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2632 /**< Alloc ID Priority used in case of Extended DBA mode */
2633 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2634 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002635
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002636 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002637 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002638 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 -05002639port_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 -08002640 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002641 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002642 OPENOLT_LOG(INFO, openolt_log_id, "Create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d, port_no %u, \
2643alloc_id %d\n", intf_id,onu_id,uni_id,port_no,alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002644 }
2645
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002646 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002647}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002648
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002649Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2650 uint32_t intf_id = traffic_scheds->intf_id();
2651 uint32_t onu_id = traffic_scheds->onu_id();
2652 uint32_t uni_id = traffic_scheds->uni_id();
2653 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002654 std::string direction;
2655 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002656 tech_profile::SchedulerConfig sched_config;
2657 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002658 uint32_t priority;
2659 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002660 tech_profile::SchedulingPolicy sched_policy;
2661 tech_profile::TrafficShapingInfo traffic_shaping_info;
2662 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002663
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002664 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2665 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002666
2667 direction = GetDirection(traffic_sched.direction());
2668 if (direction.compare("direction-not-supported") == 0)
2669 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2670
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002671 alloc_id = traffic_sched.alloc_id();
2672 sched_config = traffic_sched.scheduler();
2673 additional_bw = sched_config.additional_bw();
2674 priority = sched_config.priority();
2675 weight = sched_config.weight();
2676 sched_policy = sched_config.sched_policy();
2677 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2678 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2679 sched_policy, traffic_shaping_info);
2680 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002681 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002682 return bcm_to_grpc_err(err, "Failed to create scheduler");
2683 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002684 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002685 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002686}
Jonathan Davis70c21812018-07-19 15:32:10 -04002687
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002688bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002689
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002690 bcmos_errno err;
Jonathan Davis70c21812018-07-19 15:32:10 -04002691
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002692 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002693 bcmolt_itupon_alloc_cfg cfg;
2694 bcmolt_itupon_alloc_key key = { };
2695 key.pon_ni = intf_id;
2696 key.alloc_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002697
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002698 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
2699 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2700 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002701 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2702 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002703 return err;
2704 }
2705 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, intf_id %d, alloc_id %d\n", \
2706 direction.c_str(), intf_id, alloc_id);
2707 } else if (direction == downstream) {
2708 bcmolt_tm_sched_cfg cfg;
2709 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002710
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002711 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
2712 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2713 } else {
2714 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2715 return BCM_ERR_OK;
2716 }
2717 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2718 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2719 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002720 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
2721intf_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 +00002722 return err;
2723 }
2724 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n", \
2725 direction.c_str(), key.id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002726 }
2727
2728 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002729 return BCM_ERR_OK;
2730}
2731
2732Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2733 uint32_t intf_id = traffic_scheds->intf_id();
2734 uint32_t onu_id = traffic_scheds->onu_id();
2735 uint32_t uni_id = traffic_scheds->uni_id();
2736 std::string direction;
2737 bcmos_errno err;
2738
2739 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2740 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002741
2742 direction = GetDirection(traffic_sched.direction());
2743 if (direction.compare("direction-not-supported") == 0)
2744 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2745
2746 int alloc_id = traffic_sched.alloc_id();
2747 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002748 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002749 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002750 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2751 }
2752 }
2753 return Status::OK;
2754}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002755
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002756bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2757 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002758 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002759 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2760 bcmolt_tm_qmp_key tm_qmp_key;
2761 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002762
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002763 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2764 if (tm_qmp_id == -1) {
2765 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 -08002766 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002767
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002768 tm_qmp_key.id = tm_qmp_id;
2769 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2770 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2771 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002772
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002773 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2774 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2775 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
2776 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2777 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002778
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002779 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002780 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002781 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2782 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002783 return err;
2784 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002785
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002786 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2787 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002788 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002789}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002790
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002791bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2792 bcmos_errno err;
2793 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2794 bcmolt_tm_qmp_key tm_qmp_key;
2795 tm_qmp_key.id = tm_qmp_id;
2796
2797 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2798 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2799 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002800 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2801 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002802 return err;
2803 }
2804
2805 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2806 tm_qmp_key.id);
2807 return BCM_ERR_OK;
2808}
2809
2810bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2811 bcmos_errno err;
2812
2813 /* Create 4 Queues on given PON/NNI scheduler */
2814 for (int queue_id = 0; queue_id < 4; queue_id++) {
2815 bcmolt_tm_queue_cfg tm_queue_cfg;
2816 bcmolt_tm_queue_key tm_queue_key = {};
2817 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2818 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002819 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2820 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2821 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002822
2823 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2824 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2825 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2826
2827 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2828 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002829 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", \
2830 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 +00002831 return err;
2832 }
2833
2834 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2835 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2836 }
2837 return BCM_ERR_OK;
2838}
2839
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002840bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2841 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002842 bcmos_errno err;
2843 bcmolt_tm_queue_cfg cfg;
2844 bcmolt_tm_queue_key key = { };
2845 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
2846gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
2847
2848 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2849 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2850
2851 if (priority > 7) {
2852 return BCM_ERR_RANGE;
2853 }
2854
2855 /* FIXME: The upstream queues have to be created once only.
2856 The upstream queues on the NNI scheduler are shared by all subscribers.
2857 When the first scheduler comes in, the queues get created, and are re-used by all others.
2858 Also, these queues should be present until the last subscriber exits the system.
2859 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2860
2861 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2862 for each GEM in TECH PROFILE */
2863 key.id = queue_id_list[priority];
2864
2865 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2866 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2867 key.id = 0;
2868 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2869 }
2870 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2871 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2872 }
2873 else {
2874 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2875 }
2876
2877 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2878
2879 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2880 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2881
2882 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2883 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002884 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
2885sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n", \
2886 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 +00002887 return err;
2888 }
2889
2890 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2891intf_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);
2892 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002893}
2894
2895Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2896 uint32_t intf_id = traffic_queues->intf_id();
2897 uint32_t onu_id = traffic_queues->onu_id();
2898 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002899 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002900 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002901 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002902 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 +00002903
2904 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2905 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2906 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2907 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2908 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2909
2910 direction = GetDirection(traffic_queue.direction());
2911 if (direction.compare("direction-not-supported") == 0)
2912 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2913
2914 queues_priority_q[i] = traffic_queue.priority();
2915 queues_pbit_map[i] = traffic_queue.pbit_map();
2916 }
2917
2918 std::vector<uint32_t> tmq_map_profile(8, 0);
2919 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2920 queues_priority_q, COUNT_OF(queues_priority_q));
2921 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2922 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2923
2924 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2925 if (tm_qmp_id == -1) {
2926 CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2927 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2928 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2929 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2930 }
2931 }
2932
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002933 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2934 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002935
2936 direction = GetDirection(traffic_queue.direction());
2937 if (direction.compare("direction-not-supported") == 0)
2938 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2939
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002940 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 +00002941
Girish Gowdruf26cf882019-05-01 23:47:58 -07002942 // If the queue exists already, lets not return failure and break the loop.
2943 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002944 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002945 return bcm_to_grpc_err(err, "Failed to create queue");
2946 }
2947 }
2948 return Status::OK;
2949}
2950
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002951bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2952 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002953 bcmolt_tm_queue_cfg cfg;
2954 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002955 bcmos_errno err;
2956
2957 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002958 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
2959 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2960 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002961 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002962 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 -08002963 return BCM_ERR_OK;
2964 }
2965 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002966 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2967 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002968 return BCM_ERR_OK;
2969 }
2970
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002971 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2972 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2973 // Reset the queue id to 0 when using fixed queue.
2974 key.id = 0;
2975 }
2976 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2977 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2978 }
2979 else {
2980 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2981 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002982
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002983 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2984 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002985 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002986 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2987tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2988 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 -08002989 return err;
2990 }
2991
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002992 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2993intf_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 -08002994
2995 return BCM_ERR_OK;
2996}
2997
2998Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2999 uint32_t intf_id = traffic_queues->intf_id();
3000 uint32_t onu_id = traffic_queues->onu_id();
3001 uint32_t uni_id = traffic_queues->uni_id();
3002 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003003 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003004 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003005 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003006 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 +00003007
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003008 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
3009 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003010
3011 direction = GetDirection(traffic_queue.direction());
3012 if (direction.compare("direction-not-supported") == 0)
3013 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
3014
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003015 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 -08003016 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003017 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003018 return bcm_to_grpc_err(err, "Failed to remove queue");
3019 }
Jonathan Davis70c21812018-07-19 15:32:10 -04003020 }
3021
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003022 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))) {
3023 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
3024 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
3025
3026 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
3027 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
3028 RemoveTrafficQueueMappingProfile(tm_qmp_id);
3029 }
3030 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003031 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04003032 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04003033}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003034
3035Status check_connection() {
3036 int maxTrials = 60;
3037 while (!bcmolt_api_conn_mgr_is_connected(dev_id)) {
3038 sleep(1);
3039 if (--maxTrials == 0)
3040 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check connection failed");
3041 else
3042 OPENOLT_LOG(INFO, openolt_log_id, "waiting for daemon connection ...\n");
3043 }
3044 OPENOLT_LOG(INFO, openolt_log_id, "daemon is connected\n");
3045 return Status::OK;
3046}
3047
3048Status check_bal_ready() {
3049 bcmos_errno err;
3050 int maxTrials = 30;
3051 bcmolt_olt_cfg olt_cfg = { };
3052 bcmolt_olt_key olt_key = { };
3053
3054 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
3055 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
3056
3057 while (olt_cfg.data.bal_state != BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY) {
3058 if (--maxTrials == 0)
3059 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check bal ready failed");
3060 sleep(5);
3061 #ifdef TEST_MODE
3062 // It is impossible to mock the setting of olt_cfg.data.bal_state because
3063 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
3064 // set the olt_cfg.data.bal_state. So a new stub function is created and address
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04003065 // of olt_cfg is passed. This is one-of case where we need to add test specific
3066 // code in production code.
3067 if (bcmolt_cfg_get__bal_state_stub(dev_id, &olt_cfg)) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08003068 #else
3069 if (bcmolt_cfg_get(dev_id, &olt_cfg.hdr)) {
3070 #endif
3071 continue;
3072 }
3073 else
3074 OPENOLT_LOG(INFO, openolt_log_id, "waiting for BAL ready ...\n");
3075 }
3076
3077 OPENOLT_LOG(INFO, openolt_log_id, "BAL is ready\n");
3078 return Status::OK;
3079}