blob: 897d326bdb3846feb12883cf773d3d12a85b8d23 [file] [log] [blame]
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001/*
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002 Copyright (C) 2018 Open Networking Foundation
Shad Ansarib7b0ced2018-05-11 21:53:32 +00003
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include <iostream>
19#include <memory>
20#include <string>
21
22#include "Queue.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000023#include <sstream>
Nicolas Palpacuer9c352082018-08-14 16:37:14 -040024#include <chrono>
25#include <thread>
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080026#include <bitset>
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000027#include <inttypes.h>
Jason Huangbf45ffb2019-10-30 17:29:02 +080028#include <unistd.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000029
Craig Lutgen88a22ad2018-10-04 12:30:46 -050030#include "device.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000031#include "core.h"
32#include "indications.h"
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040033#include "stats_collection.h"
Nicolas Palpacuer73222e02018-07-16 12:20:26 -040034#include "error_format.h"
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040035#include "state.h"
Craig Lutgen88a22ad2018-10-04 12:30:46 -050036#include "utils.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000037
38extern "C"
39{
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000040#include <bcmolt_api.h>
41#include <bcmolt_host_api.h>
42#include <bcmolt_api_model_supporting_enums.h>
43
44#include <bal_version.h>
45#include <bcmolt_api_conn_mgr.h>
46//CLI header files
47#include <bcmcli_session.h>
48#include <bcmcli.h>
49#include <bcm_api_cli.h>
50
51#include <bcmos_common.h>
52#include <bcm_config.h>
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -040053// FIXME : dependency problem
54// #include <bcm_common_gpon.h>
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040055// #include <bcm_dev_log_task.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000056}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000057
Shad Ansarib7b0ced2018-05-11 21:53:32 +000058
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040059dev_log_id openolt_log_id = bcm_dev_log_id_register("OPENOLT", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
60dev_log_id omci_log_id = bcm_dev_log_id_register("OMCI", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
61
Craig Lutgen88a22ad2018-10-04 12:30:46 -050062#define BAL_RSC_MANAGER_BASE_TM_SCHED_ID 16384
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080063#define MAX_TM_QUEUE_ID 8192
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000064#define MAX_TM_QMP_ID 16
65#define TMQ_MAP_PROFILE_SIZE 8
66#define MAX_TM_SCHED_ID 1023
67#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 -080068#define EAP_ETHER_TYPE 34958
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000069#define XGS_BANDWIDTH_GRANULARITY 16000
70#define GPON_BANDWIDTH_GRANULARITY 32000
71#define FILL_ARRAY(ARRAY,START,END,VALUE) for(int i=START;i<END;ARRAY[i++]=VALUE);
72#define COUNT_OF(array) (sizeof(array) / sizeof(array[0]))
73
74#define GET_FLOW_INTERFACE_TYPE(type) \
75 (type == BCMOLT_FLOW_INTERFACE_TYPE_PON) ? "PON" : \
76 (type == BCMOLT_FLOW_INTERFACE_TYPE_NNI) ? "NNI" : \
77 (type == BCMOLT_FLOW_INTERFACE_TYPE_HOST) ? "HOST" : "unknown"
78#define GET_PKT_TAG_TYPE(type) \
79 (type == BCMOLT_PKT_TAG_TYPE_UNTAGGED) ? "UNTAG" : \
80 (type == BCMOLT_PKT_TAG_TYPE_SINGLE_TAG) ? "SINGLE_TAG" : \
81 (type == BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG) ? "DOUBLE_TAG" : "unknown"
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040082
Craig Lutgen88a22ad2018-10-04 12:30:46 -050083static unsigned int num_of_nni_ports = 0;
84static unsigned int num_of_pon_ports = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000085static std::string intf_technologies[MAX_SUPPORTED_PON];
Craig Lutgen88a22ad2018-10-04 12:30:46 -050086static const std::string UNKNOWN_TECH("unknown");
Craig Lutgenb2601f02018-10-23 13:04:31 -050087static const std::string MIXED_TECH("mixed");
88static std::string board_technology(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000089static std::string chip_family(UNKNOWN_TECH);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -080090static unsigned int OPENOLT_FIELD_LEN = 200;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000091static std::string firmware_version = "Openolt.2019.07.01";
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040092
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000093const uint32_t tm_upstream_sched_id_start = (MAX_SUPPORTED_PON == 16 ? \
94 MAX_TM_SCHED_ID-3 : MAX_TM_SCHED_ID-9);
95const uint32_t tm_downstream_sched_id_start = (MAX_SUPPORTED_PON == 16 ? \
96 tm_upstream_sched_id_start-16 : tm_upstream_sched_id_start-64);
97
98/* Max Queue ID supported is 7 so based on priority_q configured for GEMPORTS
99in TECH PROFILE respective Queue ID from this list will be used for both
100US and DS Queues*/
101const uint32_t queue_id_list[8] = {0, 1, 2, 3, 4, 5, 6, 7};
102
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700103const std::string upstream = "upstream";
104const std::string downstream = "downstream";
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000105bcmolt_oltid dev_id = 0;
106
107/* Current session */
108static bcmcli_session *current_session;
109static bcmcli_entry *api_parent_dir;
110bcmos_bool status_bcm_cli_quit = BCMOS_FALSE;
111bcmos_task bal_cli_thread;
112const char *bal_cli_thread_name = "bal_cli_thread";
113uint16_t flow_id_counters = 0;
114int flow_id_data[16384][2];
115
116/* QOS Type has been pre-defined as Fixed Queue but it will be updated based on number of GEMPORTS
117 associated for a given subscriber. If GEM count = 1 for a given subscriber, qos_type will be Fixed Queue
118 else Priority to Queue */
119bcmolt_egress_qos_type qos_type = BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700120
Shad Ansariedef2132018-08-10 22:14:50 +0000121State state;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400122
Craig Lutgen967a1d02018-11-27 10:41:51 -0600123static std::map<uint32_t, uint32_t> flowid_to_port; // For mapping upstream flows to logical ports
124static std::map<uint32_t, uint32_t> flowid_to_gemport; // For mapping downstream flows into gemports
125static 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 -0800126
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000127/* This represents the Key to 'sched_map' map.
128 Represents (pon_intf_id, onu_id, uni_id, direction) */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800129typedef std::tuple<uint32_t, uint32_t, uint32_t, std::string> sched_map_key_tuple;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000130/* 'sched_map' maps sched_map_key_tuple to DBA (Upstream) or
131 Subscriber (Downstream) Scheduler ID */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800132static std::map<sched_map_key_tuple, int> sched_map;
133
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000134/* This represents the Key to 'sched_qmp_id_map' map.
135Represents (sched_id, pon_intf_id, onu_id, uni_id) */
136typedef std::tuple<uint32_t, uint32_t, uint32_t, uint32_t> sched_qmp_id_map_key_tuple;
137/* 'sched_qmp_id_map' maps sched_qmp_id_map_key_tuple to TM Queue Mapping Profile ID */
138static std::map<sched_qmp_id_map_key_tuple, int> sched_qmp_id_map;
139/* 'qmp_id_to_qmp_map' maps TM Queue Mapping Profile ID to TM Queue Mapping Profile */
140static std::map<int, std::vector < uint32_t > > qmp_id_to_qmp_map;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800141
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800142std::bitset<MAX_TM_SCHED_ID> tm_sched_bitset;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000143std::bitset<MAX_TM_QMP_ID> tm_qmp_bitset;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800144
145static bcmos_fastlock data_lock;
Craig Lutgen967a1d02018-11-27 10:41:51 -0600146
147#define MIN_ALLOC_ID_GPON 256
148#define MIN_ALLOC_ID_XGSPON 1024
149
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800150static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
151 uint32_t port_no, uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, \
152 uint32_t priority, tech_profile::SchedulingPolicy sched_policy,
153 tech_profile::TrafficShapingInfo traffic_shaping_info);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000154static 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 -0800155static bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
156 uint32_t priority, uint32_t gemport_id);
157static bcmos_errno RemoveQueue(std::string direction, int intf_id, int onu_id, int uni_id, uint32_t port_no, int alloc_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000158static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
159static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
160
161uint16_t get_dev_id(void) {
162 return dev_id;
163}
Shad Ansari627b5782018-08-13 22:49:32 +0000164
Jason Huangbf45ffb2019-10-30 17:29:02 +0800165// Stubbed defntion of bcmolt_cfg_get required for unit-test
166extern bcmos_errno bcmolt_cfg_get_stub(bcmolt_oltid olt_id, void* ptr);
167
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800168/**
169* Returns the default NNI (Upstream direction) or PON (Downstream direction) scheduler
170* Every NNI port and PON port have default scheduler.
171* The NNI0 default scheduler ID is 18432, and NNI1 is 18433 and so on.
172* Similarly, PON0 default scheduler ID is 16384. PON1 is 16385 and so on.
173*
174* @param intf_id NNI or PON interface ID
175* @param direction "upstream" or "downstream"
176*
177* @return default scheduler ID for the given interface.
178*/
179static inline int get_default_tm_sched_id(int intf_id, std::string direction) {
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700180 if (direction.compare(upstream) == 0) {
181 return tm_upstream_sched_id_start + intf_id;
182 } else if (direction.compare(downstream) == 0) {
183 return tm_downstream_sched_id_start + intf_id;
184 }
185 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000186 OPENOLT_LOG(ERROR, openolt_log_id, "invalid direction - %s\n", direction.c_str());
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700187 return 0;
188 }
189}
190
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800191/**
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800192* Gets a unique tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
193* The tm_sched_id is locally cached in a map, so that it can rendered when necessary.
194* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
195*
196* @param intf_id NNI or PON intf ID
197* @param onu_id ONU ID
198* @param uni_id UNI ID
199* @param gemport_id GEM Port ID
200* @param direction Upstream or downstream
201*
202* @return tm_sched_id
203*/
204uint32_t get_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
205 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
206 int sched_id = -1;
207
208 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
209 if (it != sched_map.end()) {
210 sched_id = it->second;
211 }
212 if (sched_id != -1) {
213 return sched_id;
214 }
215
216 bcmos_fastlock_lock(&data_lock);
217 // Complexity of O(n). Is there better way that can avoid linear search?
218 for (sched_id = 0; sched_id < MAX_TM_SCHED_ID; sched_id++) {
219 if (tm_sched_bitset[sched_id] == 0) {
220 tm_sched_bitset[sched_id] = 1;
221 break;
222 }
223 }
224 bcmos_fastlock_unlock(&data_lock, 0);
225
226 if (sched_id < MAX_TM_SCHED_ID) {
227 bcmos_fastlock_lock(&data_lock);
228 sched_map[key] = sched_id;
229 bcmos_fastlock_unlock(&data_lock, 0);
230 return sched_id;
231 } else {
232 return -1;
233 }
234}
235
236/**
237* Free tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
238*
239* @param intf_id NNI or PON intf ID
240* @param onu_id ONU ID
241* @param uni_id UNI ID
242* @param gemport_id GEM Port ID
243* @param direction Upstream or downstream
244*/
245void free_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
246 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
247 std::map<sched_map_key_tuple, int>::const_iterator it;
248 bcmos_fastlock_lock(&data_lock);
249 it = sched_map.find(key);
250 if (it != sched_map.end()) {
251 tm_sched_bitset[it->second] = 0;
252 sched_map.erase(it);
253 }
254 bcmos_fastlock_unlock(&data_lock, 0);
255}
256
257bool is_tm_sched_id_present(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
258 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000259 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
260 if (it != sched_map.end()) {
261 return true;
262 }
263 return false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800264}
265
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000266/**
267* Check whether given two tm qmp profiles are equal or not
268*
269* @param tmq_map_profileA <vector> TM QUEUE MAPPING PROFILE
270* @param tmq_map_profileB <vector> TM QUEUE MAPPING PROFILE
271*
272* @return boolean, true if given tmq_map_profiles are equal else false
273*/
274
275bool check_tm_qmp_equality(std::vector<uint32_t> tmq_map_profileA, std::vector<uint32_t> tmq_map_profileB) {
276 for (uint32_t i = 0; i < TMQ_MAP_PROFILE_SIZE; i++) {
277 if (tmq_map_profileA[i] != tmq_map_profileB[i]) {
278 return false;
279 }
280 }
281 return true;
Shad Ansari627b5782018-08-13 22:49:32 +0000282}
283
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000284/**
285* Modifies given queues_pbit_map to parsable format
286* e.g: Modifes "0b00000101" to "10100000"
287*
288* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
289* @param size Queue count
290*
291* @return string queues_pbit_map
292*/
293std::string* get_valid_queues_pbit_map(std::string *queues_pbit_map, uint32_t size) {
294 for(uint32_t i=0; i < size; i++) {
295 /* Deletes 2 characters from index number 0 */
296 queues_pbit_map[i].erase(0, 2);
297 std::reverse(queues_pbit_map[i].begin(), queues_pbit_map[i].end());
298 }
299 return queues_pbit_map;
300}
301
302/**
303* Creates TM QUEUE MAPPING PROFILE for given queues_pbit_map and queues_priority_q
304*
305* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
306* @param queues_priority_q PRIORITY_Q configured for each GEM in TECH PROFILE
307* @param size Queue count
308*
309* @return <vector> TM QUEUE MAPPING PROFILE
310*/
311std::vector<uint32_t> get_tmq_map_profile(std::string *queues_pbit_map, uint32_t *queues_priority_q, uint32_t size) {
312 std::vector<uint32_t> tmq_map_profile(8,0);
313
314 for(uint32_t i=0; i < size; i++) {
315 for (uint32_t j = 0; j < queues_pbit_map[i].size(); j++) {
316 if (queues_pbit_map[i][j]=='1') {
317 tmq_map_profile.at(j) = queue_id_list[queues_priority_q[i]];
318 }
319 }
320 }
321 return tmq_map_profile;
322}
323
324/**
325* Gets corresponding tm_qmp_id for a given tmq_map_profile
326*
327* @param <vector> TM QUEUE MAPPING PROFILE
328*
329* @return tm_qmp_id
330*/
331int get_tm_qmp_id(std::vector<uint32_t> tmq_map_profile) {
332 int tm_qmp_id = -1;
333
334 std::map<int, std::vector < uint32_t > >::const_iterator it = qmp_id_to_qmp_map.begin();
335 while(it != qmp_id_to_qmp_map.end()) {
336 if(check_tm_qmp_equality(tmq_map_profile, it->second)) {
337 tm_qmp_id = it->first;
338 break;
339 }
340 it++;
341 }
342 return tm_qmp_id;
343}
344
345/**
346* Updates sched_qmp_id_map with given sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id
347*
348* @param upstream/downstream sched_id
349* @param PON intf ID
350* @param onu_id ONU ID
351* @param uni_id UNI ID
352* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
353*/
354void update_sched_qmp_id_map(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
355 uint32_t uni_id, int tm_qmp_id) {
356 bcmos_fastlock_lock(&data_lock);
357 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
358 sched_qmp_id_map.insert(make_pair(key, tm_qmp_id));
359 bcmos_fastlock_unlock(&data_lock, 0);
360}
361
362/**
363* Gets corresponding tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
364*
365* @param upstream/downstream sched_id
366* @param PON intf ID
367* @param onu_id ONU ID
368* @param uni_id UNI ID
369*
370* @return tm_qmp_id
371*/
372int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
373 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
374 int tm_qmp_id = -1;
375
376 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
377 if (it != sched_qmp_id_map.end()) {
378 tm_qmp_id = it->second;
379 }
380 return tm_qmp_id;
381}
382
383/**
384* Gets a unique tm_qmp_id for a given tmq_map_profile
385* The tm_qmp_id is locally cached in a map, so that it can be rendered when necessary.
386* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
387*
388* @param upstream/downstream sched_id
389* @param PON intf ID
390* @param onu_id ONU ID
391* @param uni_id UNI ID
392* @param <vector> TM QUEUE MAPPING PROFILE
393*
394* @return tm_qmp_id
395*/
396int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, \
397 std::vector<uint32_t> tmq_map_profile) {
398 int tm_qmp_id;
399
400 bcmos_fastlock_lock(&data_lock);
401 /* Complexity of O(n). Is there better way that can avoid linear search? */
402 for (tm_qmp_id = 0; tm_qmp_id < MAX_TM_QMP_ID; tm_qmp_id++) {
403 if (tm_qmp_bitset[tm_qmp_id] == 0) {
404 tm_qmp_bitset[tm_qmp_id] = 1;
405 break;
406 }
407 }
408 bcmos_fastlock_unlock(&data_lock, 0);
409
410 if (tm_qmp_id < MAX_TM_QMP_ID) {
411 bcmos_fastlock_lock(&data_lock);
412 qmp_id_to_qmp_map.insert(make_pair(tm_qmp_id, tmq_map_profile));
413 bcmos_fastlock_unlock(&data_lock, 0);
414 update_sched_qmp_id_map(sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id);
415 return tm_qmp_id;
416 } else {
417 return -1;
418 }
419}
420
421/**
422* Free tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
423*
424* @param upstream/downstream sched_id
425* @param PON intf ID
426* @param onu_id ONU ID
427* @param uni_id UNI ID
428* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
429*
430* @return boolean, true if no more reference for TM QMP else false
431*/
432bool free_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
433 uint32_t uni_id, int tm_qmp_id) {
434 bool result;
435 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
436 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
437 bcmos_fastlock_lock(&data_lock);
438 if (it != sched_qmp_id_map.end()) {
439 sched_qmp_id_map.erase(it);
440 }
441 bcmos_fastlock_unlock(&data_lock, 0);
442
443 uint32_t tm_qmp_ref_count = 0;
444 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it2 = sched_qmp_id_map.begin();
445 while(it2 != sched_qmp_id_map.end()) {
446 if(it2->second == tm_qmp_id) {
447 tm_qmp_ref_count++;
448 }
449 it2++;
450 }
451
452 if (tm_qmp_ref_count == 0) {
453 std::map<int, std::vector < uint32_t > >::const_iterator it3 = qmp_id_to_qmp_map.find(tm_qmp_id);
454 if (it3 != qmp_id_to_qmp_map.end()) {
455 bcmos_fastlock_lock(&data_lock);
456 tm_qmp_bitset[tm_qmp_id] = 0;
457 qmp_id_to_qmp_map.erase(it3);
458 bcmos_fastlock_unlock(&data_lock, 0);
459 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So clearing it\n", \
460 tm_qmp_id, tm_qmp_ref_count);
461 result = true;
462 }
463 } else {
464 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So not clearing it\n", \
465 tm_qmp_id, tm_qmp_ref_count);
466 result = false;
467 }
468 return result;
469}
470
471/**
472* Returns Scheduler/Queue direction as string
473*
474* @param direction as specified in tech_profile.proto
475*/
476std::string GetDirection(int direction) {
477 switch (direction)
478 {
479 case tech_profile::Direction::UPSTREAM: return upstream;
480 case tech_profile::Direction::DOWNSTREAM: return downstream;
481 default: OPENOLT_LOG(ERROR, openolt_log_id, "direction-not-supported %d\n", direction);
482 return "direction-not-supported";
483 }
484}
485
486inline const char *get_flow_acton_command(uint32_t command) {
487 char actions[200] = { };
488 char *s_actions_ptr = actions;
489 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
490 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
491 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
492 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
493 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
494 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
495 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
496 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
497 return s_actions_ptr;
498}
499
500char* openolt_read_sysinfo(const char* field_name, char* field_val)
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800501{
502 FILE *fp;
503 /* Prepare the command*/
504 char command[150];
505
506 snprintf(command, sizeof command, "bash -l -c \"onlpdump -s\" | perl -ne 'print $1 if /%s: (\\S+)/'", field_name);
507 /* Open the command for reading. */
508 fp = popen(command, "r");
509 if (fp == NULL) {
510 /*The client has to check for a Null field value in this case*/
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000511 OPENOLT_LOG(INFO, openolt_log_id, "Failed to query the %s\n", field_name);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800512 return field_val;
513 }
514
515 /*Read the field value*/
516 if (fp) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000517 uint8_t ret;
518 ret = fread(field_val, OPENOLT_FIELD_LEN, 1, fp);
519 if (ret >= OPENOLT_FIELD_LEN)
520 OPENOLT_LOG(INFO, openolt_log_id, "Read data length %u\n", ret);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800521 pclose(fp);
522 }
523 return field_val;
524}
525
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400526Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500527 device_info->set_vendor(VENDOR_ID);
528 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400529 device_info->set_hardware_version("");
530 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500531 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500532 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500533
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800534 char serial_number[OPENOLT_FIELD_LEN];
535 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
536 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000537 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800538 device_info->set_device_serial_number(serial_number);
539
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700540 char device_id[OPENOLT_FIELD_LEN];
541 memset(device_id, '\0', OPENOLT_FIELD_LEN);
542 openolt_read_sysinfo("MAC", device_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000543 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700544 device_info->set_device_id(device_id);
545
Craig Lutgenb2601f02018-10-23 13:04:31 -0500546 // Legacy, device-wide ranges. To be deprecated when adapter
547 // is upgraded to support per-interface ranges
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000548 if (board_technology == "XGS-PON") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500549 device_info->set_onu_id_start(1);
550 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600551 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500552 device_info->set_alloc_id_end(16383);
553 device_info->set_gemport_id_start(1024);
554 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500555 device_info->set_flow_id_start(1);
556 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500557 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000558 else if (board_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500559 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500560 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600561 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500562 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500563 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500564 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500565 device_info->set_flow_id_start(1);
566 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500567 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500568
569 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
570 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
571 std::string intf_technology = intf_technologies[intf_id];
572 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
573 if(range == nullptr) {
574 range = device_info->add_ranges();
575 ranges[intf_technology] = range;
576 range->set_technology(intf_technology);
577
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000578 if (intf_technology == "XGS-PON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500579 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
580
581 pool = range->add_pools();
582 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
583 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
584 pool->set_start(1);
585 pool->set_end(255);
586
587 pool = range->add_pools();
588 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
589 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
590 pool->set_start(1024);
591 pool->set_end(16383);
592
593 pool = range->add_pools();
594 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
595 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
596 pool->set_start(1024);
597 pool->set_end(65535);
598
599 pool = range->add_pools();
600 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
601 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
602 pool->set_start(1);
603 pool->set_end(16383);
604 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000605 else if (intf_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500606 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
607
608 pool = range->add_pools();
609 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
610 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
611 pool->set_start(1);
612 pool->set_end(127);
613
614 pool = range->add_pools();
615 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
616 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
617 pool->set_start(256);
618 pool->set_end(757);
619
620 pool = range->add_pools();
621 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
622 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
623 pool->set_start(256);
624 pool->set_end(4095);
625
626 pool = range->add_pools();
627 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
628 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
629 pool->set_start(1);
630 pool->set_end(16383);
631 }
632 }
633
634 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500635 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400636
637 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500638 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400639 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
640 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500641 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400642 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500643 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
644 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400645
646 return Status::OK;
647}
648
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000649Status pushOltOperInd(uint32_t intf_id, const char *type, const char *state)
650{
651 openolt::Indication ind;
652 openolt::IntfOperIndication* intf_oper_ind = new openolt::IntfOperIndication;
653
654 intf_oper_ind->set_type(type);
655 intf_oper_ind->set_intf_id(intf_id);
656 intf_oper_ind->set_oper_state(state);
657 ind.set_allocated_intf_oper_ind(intf_oper_ind);
658 oltIndQ.push(ind);
659 return Status::OK;
660}
661
662#define CLI_HOST_PROMPT_FORMAT "BCM.%u> "
663
664/* Build CLI prompt */
665static void openolt_cli_get_prompt_cb(bcmcli_session *session, char *buf, uint32_t max_len)
666{
667 snprintf(buf, max_len, CLI_HOST_PROMPT_FORMAT, dev_id);
668}
669
670static int _bal_apiend_cli_thread_handler(long data)
671{
672 char init_string[]="\n";
673 bcmcli_session *sess = current_session;
674 bcmos_task_parm bal_cli_task_p_dummy;
675
676 /* Switch to interactive mode if not stopped in the init script */
677 if (!bcmcli_is_stopped(sess))
678 {
679 /* Force a CLI command prompt
680 * The string passed into the parse function
681 * must be modifiable, so a string constant like
682 * bcmcli_parse(current_session, "\n") will not
683 * work.
684 */
685 bcmcli_parse(sess, init_string);
686
687 /* Process user input until EOF or quit command */
688 bcmcli_driver(sess);
689 };
690 OPENOLT_LOG(INFO, openolt_log_id, "BAL API End CLI terminated\n");
691
692 /* Cleanup */
693 bcmcli_session_close(current_session);
694 bcmcli_token_destroy(NULL);
695 return 0;
696}
697
698/* Init API CLI commands for the current device */
699bcmos_errno bcm_openolt_api_cli_init(bcmcli_entry *parent_dir, bcmcli_session *session)
700{
701 bcmos_errno rc;
702
703 api_parent_dir = parent_dir;
704
705 rc = bcm_api_cli_set_commands(session);
706
707#ifdef BCM_SUBSYSTEM_HOST
708 /* Subscribe for device change indication */
709 rc = rc ? rc : bcmolt_olt_sel_ind_register(_api_cli_olt_change_ind);
710#endif
711
712 return rc;
713}
714
715static bcmos_errno bcm_cli_quit(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
716{
717 bcmcli_stop(session);
718 bcmcli_session_print(session, "CLI terminated by 'Quit' command\n");
719 status_bcm_cli_quit = BCMOS_TRUE;
720
721 return BCM_ERR_OK;
722}
723
724int get_status_bcm_cli_quit(void) {
725 return status_bcm_cli_quit;
726}
727
728bcmos_errno bcmolt_apiend_cli_init() {
729 bcmos_errno ret;
730 bcmos_task_parm bal_cli_task_p = {};
731 bcmos_task_parm bal_cli_task_p_dummy;
732
733 /** before creating the task, check if it is already created by the other half of BAL i.e. Core side */
734 if (BCM_ERR_OK != bcmos_task_query(&bal_cli_thread, &bal_cli_task_p_dummy))
735 {
736 /* Create BAL CLI thread */
737 bal_cli_task_p.name = bal_cli_thread_name;
738 bal_cli_task_p.handler = _bal_apiend_cli_thread_handler;
739 bal_cli_task_p.priority = TASK_PRIORITY_CLI;
740
741 ret = bcmos_task_create(&bal_cli_thread, &bal_cli_task_p);
742 if (BCM_ERR_OK != ret)
743 {
744 bcmos_printf("Couldn't create BAL API end CLI thread\n");
745 return ret;
746 }
747 }
748}
749
Shad Ansari627b5782018-08-13 22:49:32 +0000750Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000751 bcmos_errno err;
752 bcmolt_host_init_parms init_parms = {};
753 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
754 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000755
Shad Ansariedef2132018-08-10 22:14:50 +0000756 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000757
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500758 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000759 /* Initialize host subsystem */
760 err = bcmolt_host_init(&init_parms);
761 if (BCM_ERR_OK != err) {
762 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT\n");
763 return bcm_to_grpc_err(err, "Failed to init OLT");
764 }
765
766 bcmcli_session_parm mon_session_parm;
767 /* Create CLI session */
768 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
769 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
770 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
771 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
772 BUG_ON(rc != BCM_ERR_OK);
773
774 /* API CLI */
775 bcm_openolt_api_cli_init(NULL, current_session);
776
777 /* Add quit command */
778 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
779
780 err = bcmolt_apiend_cli_init();
781 if (BCM_ERR_OK != err) {
782 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init\n");
783 return bcm_to_grpc_err(err, "Failed to add apiend init");
784 }
785
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800786 bcmos_fastlock_init(&data_lock, 0);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000787 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600788
Jason Huangbf45ffb2019-10-30 17:29:02 +0800789 //check BCM daemon is connected or not
790 Status status = check_connection();
791 if (!status.ok())
792 return status;
793 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000794 Status status = SubscribeIndication();
795 if (!status.ok()) {
796 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
797 grpc_status_code_to_string(status.error_code()).c_str(),
798 status.error_message().c_str());
799 return status;
800 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800801
802 //check BAL state in initial stage
803 status = check_bal_ready();
804 if (!status.ok())
805 return status;
806 }
807
808 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000809 bcmos_errno err;
810 bcmolt_odid dev;
811 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
812 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
813 bcmolt_device_cfg dev_cfg = { };
814 bcmolt_device_key dev_key = { };
815 dev_key.device_id = dev;
816 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
817 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
818 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800819 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000820 bcmolt_device_key key = {.device_id = dev};
821 bcmolt_device_connect oper;
822 BCMOLT_OPER_INIT(&oper, device, connect, key);
823 if (MODEL_ID == "asfvolt16") {
824 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
825 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
826 } else if (MODEL_ID == "asgvolt64") {
827 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
828 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
829 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
830 }
831 err = bcmolt_oper_submit(dev_id, &oper.hdr);
832 if (err) {
833 failed_enable_device_cnt ++;
834 OPENOLT_LOG(ERROR, openolt_log_id, "Enable PON device %d failed, err %d\n", dev, err);
835 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
836 OPENOLT_LOG(ERROR, openolt_log_id, "failed to enable all the pon ports\n");
837 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
838 }
839 }
840 bcmos_usleep(200000);
841 }
842 else {
843 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
844 state.activate();
845 }
846 }
847 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000848 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000849 }
Shad Ansariedef2132018-08-10 22:14:50 +0000850
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000851 /* Start CLI */
852 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400853 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000854 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400855}
856
857Status Disable_() {
858 // bcmbal_access_terminal_cfg acc_term_obj;
859 // bcmbal_access_terminal_key key = { };
860 //
861 // if (state::is_activated) {
862 // std::cout << "Disable OLT" << std::endl;
863 // key.access_term_id = DEFAULT_ATERM_ID;
864 // BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
865 // BCMBAL_CFG_PROP_SET(&acc_term_obj, access_terminal, admin_state, BCMBAL_STATE_DOWN);
866 // bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
867 // if (err) {
868 // std::cout << "ERROR: Failed to disable OLT" << std::endl;
869 // return bcm_to_grpc_err(err, "Failed to disable OLT");
870 // }
871 // }
872 // //If already disabled, generate an extra indication ????
873 // return Status::OK;
874 //This fails with Operation Not Supported, bug ???
875
876 //TEMPORARY WORK AROUND
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000877 Status status = SetStateUplinkIf_(nni_intf_id, false);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400878 if (status.ok()) {
Shad Ansariedef2132018-08-10 22:14:50 +0000879 state.deactivate();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000880 OPENOLT_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
881 pushOltOperInd(nni_intf_id, "nni", "up");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400882 }
883 return status;
884
885}
886
887Status Reenable_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000888 Status status = SetStateUplinkIf_(0, true);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400889 if (status.ok()) {
Shad Ansariedef2132018-08-10 22:14:50 +0000890 state.activate();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000891 OPENOLT_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
892 pushOltOperInd(0, "nni", "up");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400893 }
894 return status;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000895}
896
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000897bcmos_errno get_pon_interface_status(bcmolt_interface pon_ni, bcmolt_interface_state *state) {
898 bcmos_errno err;
899 bcmolt_pon_interface_key pon_key;
900 bcmolt_pon_interface_cfg pon_cfg;
901 pon_key.pon_ni = pon_ni;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000902
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000903 BCMOLT_CFG_INIT(&pon_cfg, pon_interface, pon_key);
904 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, state);
905 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, itu);
906 err = bcmolt_cfg_get(dev_id, &pon_cfg.hdr);
907 *state = pon_cfg.data.state;
908 return err;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000909}
910
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000911inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
912 bcmos_errno err;
913 bcmolt_flow_key flow_key;
914 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400915
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000916 flow_key.flow_id = flow_id;
917 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400918
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000919 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400920
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000921 switch (data_id) {
922 case ONU_ID: //onu_id
923 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
924 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
925 if (err) {
926 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id\n");
927 return err;
928 }
929 return flow_cfg.data.onu_id;
930 case FLOW_TYPE:
931 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
932 if (err) {
933 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type\n");
934 return err;
935 }
936 return flow_cfg.key.flow_type;
937 case SVC_PORT_ID: //svc_port_id
938 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
939 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
940 if (err) {
941 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get svc_port_id\n");
942 return err;
943 }
944 return flow_cfg.data.svc_port_id;
945 case PRIORITY:
946 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
947 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
948 if (err) {
949 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority\n");
950 return err;
951 }
952 return flow_cfg.data.priority;
953 case COOKIE: //cookie
954 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
955 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
956 if (err) {
957 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie\n");
958 return err;
959 }
960 return flow_cfg.data.cookie;
961 case INGRESS_INTF_TYPE: //ingress intf_type
962 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
963 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
964 if (err) {
965 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_type\n");
966 return err;
967 }
968 return flow_cfg.data.ingress_intf.intf_type;
969 case EGRESS_INTF_TYPE: //egress intf_type
970 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
971 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
972 if (err) {
973 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_type\n");
974 return err;
975 }
976 return flow_cfg.data.egress_intf.intf_type;
977 case INGRESS_INTF_ID: //ingress intf_id
978 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
979 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
980 if (err) {
981 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_id\n");
982 return err;
983 }
984 return flow_cfg.data.ingress_intf.intf_id;
985 case EGRESS_INTF_ID: //egress intf_id
986 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
987 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
988 if (err) {
989 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_id\n");
990 return err;
991 }
992 return flow_cfg.data.egress_intf.intf_id;
993 case CLASSIFIER_O_VID:
994 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
995 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
996 if (err) {
997 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_vid\n");
998 return err;
999 }
1000 return flow_cfg.data.classifier.o_vid;
1001 case CLASSIFIER_O_PBITS:
1002 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1003 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1004 if (err) {
1005 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_pbits\n");
1006 return err;
1007 }
1008 return flow_cfg.data.classifier.o_pbits;
1009 case CLASSIFIER_I_VID:
1010 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1011 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1012 if (err) {
1013 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_vid\n");
1014 return err;
1015 }
1016 return flow_cfg.data.classifier.i_vid;
1017 case CLASSIFIER_I_PBITS:
1018 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1019 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1020 if (err) {
1021 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_pbits\n");
1022 return err;
1023 }
1024 return flow_cfg.data.classifier.i_pbits;
1025 case CLASSIFIER_ETHER_TYPE:
1026 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1027 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1028 if (err) {
1029 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ether_type\n");
1030 return err;
1031 }
1032 return flow_cfg.data.classifier.ether_type;
1033 case CLASSIFIER_IP_PROTO:
1034 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1035 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1036 if (err) {
1037 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ip_proto\n");
1038 return err;
1039 }
1040 return flow_cfg.data.classifier.ip_proto;
1041 case CLASSIFIER_SRC_PORT:
1042 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1043 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1044 if (err) {
1045 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier src_port\n");
1046 return err;
1047 }
1048 return flow_cfg.data.classifier.src_port;
1049 case CLASSIFIER_DST_PORT:
1050 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1051 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1052 if (err) {
1053 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier dst_port\n");
1054 return err;
1055 }
1056 return flow_cfg.data.classifier.dst_port;
1057 case CLASSIFIER_PKT_TAG_TYPE:
1058 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1059 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1060 if (err) {
1061 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier pkt_tag_type\n");
1062 return err;
1063 }
1064 return flow_cfg.data.classifier.pkt_tag_type;
1065 case EGRESS_QOS_TYPE:
1066 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1067 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1068 if (err) {
1069 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos type\n");
1070 return err;
1071 }
1072 return flow_cfg.data.egress_qos.type;
1073 case EGRESS_QOS_QUEUE_ID:
1074 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1075 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1076 if (err) {
1077 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos queue_id\n");
1078 return err;
1079 }
1080 switch (flow_cfg.data.egress_qos.type) {
1081 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
1082 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
1083 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
1084 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
1085 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
1086 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
1087 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
1088 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
1089 case BCMOLT_EGRESS_QOS_TYPE_NONE:
1090 default:
1091 return -1;
1092 }
1093 case EGRESS_QOS_TM_SCHED_ID:
1094 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1095 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1096 if (err) {
1097 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos tm_sched_id\n");
1098 return err;
1099 }
1100 return flow_cfg.data.egress_qos.tm_sched.id;
1101 case ACTION_CMDS_BITMASK:
1102 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1103 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1104 if (err) {
1105 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action cmds_bitmask\n");
1106 return err;
1107 }
1108 return flow_cfg.data.action.cmds_bitmask;
1109 case ACTION_O_VID:
1110 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1111 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1112 if (err) {
1113 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_vid\n");
1114 return err;
1115 }
1116 return flow_cfg.data.action.o_vid;
1117 case ACTION_O_PBITS:
1118 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1119 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1120 if (err) {
1121 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_pbits\n");
1122 return err;
1123 }
1124 return flow_cfg.data.action.o_pbits;
1125 case ACTION_I_VID:
1126 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1127 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1128 if (err) {
1129 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_vid\n");
1130 return err;
1131 }
1132 return flow_cfg.data.action.i_vid;
1133 case ACTION_I_PBITS:
1134 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1135 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1136 if (err) {
1137 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_pbits\n");
1138 return err;
1139 }
1140 return flow_cfg.data.action.i_pbits;
1141 case STATE:
1142 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
1143 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1144 if (err) {
1145 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state\n");
1146 return err;
1147 }
1148 return flow_cfg.data.state;
1149 default:
1150 return BCM_ERR_INTERNAL;
1151 }
1152
1153 return err;
1154}
1155
1156Status EnablePonIf_(uint32_t intf_id) {
1157 bcmos_errno err = BCM_ERR_OK;
1158 bcmolt_pon_interface_cfg interface_obj;
1159 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1160 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
1161 bcmolt_interface_state state;
1162
1163 err = get_pon_interface_status((bcmolt_interface)intf_id, &state);
1164 if (err == BCM_ERR_OK) {
1165 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001166 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001167 return Status::OK;
1168 }
1169 }
1170 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1171 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1172 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
1173 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
1174 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
1175 BCMOLT_ONU_POST_DISCOVERY_MODE_ACTIVATE);
1176 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
1177 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
1178 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
1179 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
1180 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
1181 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
1182 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1183 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1184
1185 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1186 if (err != BCM_ERR_OK) {
1187 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable discovery onu, PON interface %d, err %d\n", intf_id, err);
1188 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
1189 }
1190 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1191 if (err != BCM_ERR_OK) {
1192 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", intf_id);
1193 return bcm_to_grpc_err(err, "Failed to enable PON interface");
1194 }
1195 else {
1196 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
1197 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
1198 CreateDefaultSched(intf_id, downstream);
1199 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001200 }
1201
1202 return Status::OK;
1203}
1204
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001205Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001206 bcmos_errno err;
1207 bcmolt_device_cfg dev_cfg = { };
1208 bcmolt_device_key dev_key = { };
1209 bcmolt_olt_cfg olt_cfg = { };
1210 bcmolt_olt_key olt_key = { };
1211 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
1212 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001213
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001214 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
1215 topo.topology_maps.arr = &topo_map[0];
1216 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
1217 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
1218 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
1219 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
1220 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
1221 err = bcmolt_cfg_get(dev_id, &olt_cfg.hdr);
1222 if (err) {
1223 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query OLT\n");
1224 return bcm_to_grpc_err(err, "cfg: Failed to query OLT");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001225 }
1226
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001227 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
1228 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001229
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001230 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
1231 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
1232 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001233
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001234 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
1235 num_of_nni_ports,
1236 num_of_pon_ports,
1237 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001238
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001239 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1240 dev_key.device_id = devid;
1241 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1242 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1243 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1244 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
1245 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
1246 if (err) {
1247 OPENOLT_LOG(ERROR, openolt_log_id, "device: Failed to query OLT\n");
1248 return bcm_to_grpc_err(err, "device: Failed to query OLT");
1249 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001250
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001251 std::string bal_version;
1252 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1253 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1254 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
1255 firmware_version = "BAL." + bal_version + "__" + firmware_version;
1256
1257 switch(dev_cfg.data.system_mode) {
1258 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1259 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1260 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1261 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1262 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1263 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1264 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1265 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1266 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1267 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1268 }
1269
1270 switch(dev_cfg.data.chip_family) {
1271 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X_: chip_family = "Maple"; break;
1272 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X_: chip_family = "Aspen"; break;
1273 }
1274
1275 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s object model: %d, family: %s, board_technology: %s\n",
1276 devid, BCM_MAX_PONS_PER_DEV, bal_version.c_str(), BAL_API_VERSION, chip_family.c_str(), board_technology.c_str());
1277
1278 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001279 }
1280
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001281 return Status::OK;
1282}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001283#if 0
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001284Status ProbePonIfTechnology_() {
1285 // Probe maximum extent possible as configured into BAL driver to determine
1286 // which are active in the current BAL topology. And for those
1287 // that are active, determine each port's access technology, i.e. "gpon" or "xgspon".
1288 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001289 bcmolt_pon_interface_cfg interface_obj;
1290 bcmolt_pon_interface_key interface_key;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001291
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001292 interface_key.pon_ni = intf_id;
1293 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
1294 if (board_technology == "XGS-PON")
1295 BCMOLT_MSG_FIELD_GET(&interface_obj, xgs_ngpon2_trx);
1296 else if (board_technology == "GPON")
1297 BCMOLT_MSG_FIELD_GET(&interface_obj, gpon_trx);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001298
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001299 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001300 if (err != BCM_ERR_OK) {
Craig Lutgenb2601f02018-10-23 13:04:31 -05001301 intf_technologies[intf_id] = UNKNOWN_TECH;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001302 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 -05001303 }
1304 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001305 if (board_technology == "XGS-PON") {
1306 switch(interface_obj.data.xgpon_trx.transceiver_type) {
1307 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_PC:
1308 case BCMOLT_XGPON_TRX_TYPE_WTD_RTXM266_702:
1309 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_BC_PLUS:
1310 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_PC:
1311 case BCMOLT_XGPON_TRX_TYPE_LTH_5302_PC:
1312 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_A_PC_PLUS:
1313 case BCMOLT_XGPON_TRX_TYPE_D272RR_SSCB_DM:
1314 intf_technologies[intf_id] = "XGS-PON";
1315 break;
1316 }
1317 } else if (board_technology == "GPON") {
1318 switch(interface_obj.data.gpon_trx.transceiver_type) {
1319 case BCMOLT_TRX_TYPE_SPS_43_48_H_HP_CDE_SD_2013:
1320 case BCMOLT_TRX_TYPE_LTE_3680_M:
1321 case BCMOLT_TRX_TYPE_SOURCE_PHOTONICS:
1322 case BCMOLT_TRX_TYPE_LTE_3680_P_TYPE_C_PLUS:
1323 case BCMOLT_TRX_TYPE_LTE_3680_P_BC:
1324 intf_technologies[intf_id] = "GPON";
1325 break;
1326 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001327 }
Craig Lutgenb2601f02018-10-23 13:04:31 -05001328
1329 if (board_technology != UNKNOWN_TECH) {
1330 board_technology = intf_technologies[intf_id];
1331 } else if (board_technology != MIXED_TECH && board_technology != intf_technologies[intf_id]) {
1332 intf_technologies[intf_id] = MIXED_TECH;
1333 }
1334
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001335 }
1336 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001337 return Status::OK;
1338}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001339#endif
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001340unsigned NumNniIf_() {return num_of_nni_ports;}
1341unsigned NumPonIf_() {return num_of_pon_ports;}
1342
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001343bcmos_errno get_nni_interface_status(bcmolt_interface id, bcmolt_interface_state *state) {
1344 bcmos_errno err;
1345 bcmolt_nni_interface_key nni_key;
1346 bcmolt_nni_interface_cfg nni_cfg;
1347 nni_key.id = id;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001348
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001349 BCMOLT_CFG_INIT(&nni_cfg, nni_interface, nni_key);
1350 BCMOLT_FIELD_SET_PRESENT(&nni_cfg.data, nni_interface_cfg_data, state);
1351 err = bcmolt_cfg_get(dev_id, &nni_cfg.hdr);
1352 *state = nni_cfg.data.state;
1353 return err;
1354}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001355
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001356Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
1357 bcmos_errno err = BCM_ERR_OK;
1358 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1359 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1360 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001361
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001362 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
1363 if (err == BCM_ERR_OK) {
1364 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001365 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001366 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1367 CreateDefaultSched(intf_id, upstream);
1368 CreateDefaultQueue(intf_id, upstream);
1369 return Status::OK;
1370 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1371 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1372 return Status::OK;
1373 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001374 }
1375
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001376 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1377 if (set_state) {
1378 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1379 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1380 } else {
1381 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1382 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1383 }
1384 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1385 if (err != BCM_ERR_OK) {
1386 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err %d\n",
1387 (set_state)?"enable":"disable", intf_id, err);
1388 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1389 }
1390 else {
1391 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1392 if (set_state) {
1393 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1394 CreateDefaultSched(intf_id, upstream);
1395 CreateDefaultQueue(intf_id, upstream);
1396 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001397 }
1398
1399 return Status::OK;
1400}
1401
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001402Status DisablePonIf_(uint32_t intf_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001403 bcmolt_pon_interface_cfg interface_obj;
1404 bcmolt_pon_interface_key interface_key;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001405
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001406 interface_key.pon_ni = intf_id;
1407 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
1408 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1409 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001410 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001411 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", intf_id);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001412 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001413 }
1414
1415 return Status::OK;
1416}
1417
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001418Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001419 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001420 bcmos_errno err = BCM_ERR_OK;
1421 bcmolt_onu_cfg onu_cfg;
1422 bcmolt_onu_key onu_key;
1423 bcmolt_serial_number serial_number; /**< ONU serial number */
1424 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001425
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001426 onu_key.onu_id = onu_id;
1427 onu_key.pon_ni = intf_id;
1428 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1429 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1430 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
1431 if (err == BCM_ERR_OK) {
1432 if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING ||
1433 onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) ||
1434 (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_INACTIVE &&
1435 onu_cfg.data.onu_old_state == BCMOLT_ONU_STATE_NOT_CONFIGURED))
1436 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001437 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001438
1439 OPENOLT_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, \
1440vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
1441 vendor_specific_to_str(vendor_specific).c_str(), pir);
1442
1443 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1444 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1445 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1446 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1447 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1448 /*set burst and data profiles to fec disabled*/
1449 if (board_technology == "XGS-PON") {
1450 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1451 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1452 } else if (board_technology == "GPON") {
1453 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1454 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1455 }
1456 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1457 if (err != BCM_ERR_OK) {
1458 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to set activate ONU %d on PON %d, err %d\n", onu_id, intf_id, err);
1459 return bcm_to_grpc_err(err, "Failed to activate ONU");
1460 }
1461
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001462 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001463}
1464
Jonathan Davis70c21812018-07-19 15:32:10 -04001465Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1466 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001467 bcmos_errno err = BCM_ERR_OK;
1468 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1469 bcmolt_onu_cfg onu_cfg;
1470 bcmolt_onu_key onu_key; /**< Object key. */
1471 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001472
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001473 onu_key.onu_id = onu_id;
1474 onu_key.pon_ni = intf_id;
1475 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1476 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1477 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
1478 if (err == BCM_ERR_OK) {
1479 switch (onu_state) {
1480 case BCMOLT_ONU_OPERATION_ACTIVE:
1481 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1482 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1483 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1484 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1485 if (err != BCM_ERR_OK) {
1486 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to \
1487deactivate ONU %d on PON %d, err %d\n", onu_id, intf_id, err);
1488 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1489 }
1490 break;
1491 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001492 }
1493
1494 return Status::OK;
1495}
1496
1497Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001498 const char *vendor_id, const char *vendor_specific) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001499
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001500 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 -05001501 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1502
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001503 // Need to deactivate before removing it (BAL rules)
1504
1505 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1506 // Sleep to allow the state to propagate
1507 // We need the subscriber terminal object to be admin down before removal
1508 // Without sleep the race condition is lost by ~ 20 ms
1509 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1510
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001511 // TODO: Delete the schedulers and queues.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001512
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001513 bcmolt_onu_cfg cfg_obj;
1514 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001515
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001516 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 -04001517 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001518
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001519 key.onu_id = onu_id;
1520 key.pon_ni = intf_id;
1521 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001522
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001523 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001524 if (err != BCM_ERR_OK)
1525 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001526 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL subscriber_terminal_id %d, Interface ID %d\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001527 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001528 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1529 }
1530
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001531 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001532}
1533
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001534#define MAX_CHAR_LENGTH 20
1535#define MAX_OMCI_MSG_LENGTH 44
1536Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001537 bcmolt_bin_str buf = {};
1538 bcmolt_onu_cpu_packets omci_cpu_packets;
1539 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001540
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001541 key.pon_ni = intf_id;
1542 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001543
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001544 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1545 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1546 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001547
1548 // ???
1549 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1550 buf.len = MAX_OMCI_MSG_LENGTH;
1551 } else {
1552 buf.len = pkt.size()/2;
1553 }
1554
1555 /* Send the OMCI packet using the BAL remote proxy API */
1556 uint16_t idx1 = 0;
1557 uint16_t idx2 = 0;
1558 uint8_t arraySend[buf.len];
1559 char str1[MAX_CHAR_LENGTH];
1560 char str2[MAX_CHAR_LENGTH];
1561 memset(&arraySend, 0, buf.len);
1562
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001563 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1564 sprintf(str1,"%c", pkt[idx1]);
1565 sprintf(str2,"%c", pkt[++idx1]);
1566 strcat(str1,str2);
1567 arraySend[idx2] = strtol(str1, NULL, 16);
1568 }
1569
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001570 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1571 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001572
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001573 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1574 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1575 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001576
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001577 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001578 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001579 OPENOLT_LOG(ERROR, omci_log_id, "Error sending OMCI message to ONU %d on PON %d\n", onu_id, intf_id);
1580 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001581 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001582 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 -05001583 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001584 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001585 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001586
1587 return Status::OK;
1588}
1589
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001590Status 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 +00001591 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1592 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1593 bcmolt_bin_str buf = {};
1594 bcmolt_gem_port_id gem_port_id_array[1];
1595 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001596
Craig Lutgen967a1d02018-11-27 10:41:51 -06001597 if (port_no > 0) {
1598 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001599 if (gemport_id == 0) {
1600 bcmos_fastlock_lock(&data_lock);
1601 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1602 // Pick any flow that is mapped with the same port_no.
1603 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1604 if (it != port_to_flows.end() && !it->second.empty()) {
1605 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1606 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1607 if (fit != flowid_to_gemport.end()) {
1608 found = true;
1609 gemport_id = fit->second;
1610 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001611 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001612 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001613
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001614 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001615 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 -08001616 onu_id, port_no, intf_id);
1617 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1618 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001619 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 -08001620 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001621 }
1622
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001623 gem_port_id_array[0] = gemport_id;
1624 gem_port_list.len = 1;
1625 gem_port_list.arr = gem_port_id_array;
1626 buf.len = pkt.size();
1627 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1628 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1629
1630 /* init the API struct */
1631 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1632 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1633 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1634 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1635 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1636
1637 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1638 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1639
1640 /* call API */
1641 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001642 }
1643 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001644 //TODO: Port No is 0, it is coming sender requirement.
1645 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1646 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001647 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001648 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001649
1650 return Status::OK;
1651}
1652
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001653Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001654 bcmolt_flow_key key = {}; /* declare key */
1655 bcmolt_bin_str buffer = {};
1656 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001657
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001658 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1659 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001660
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001661 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1662 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1663 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1664 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1665 key.flow_id = flow_id;
1666 else {
1667 if (flow_id_counters != 0) {
1668 for (int flowid=0; flowid < flow_id_counters; flowid++) {
1669 int flow_index = flow_id_data[flowid][0];
1670 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1671 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1672 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1673 key.flow_id = flow_index;
1674 break;
1675 }
1676 }
1677 }
1678 else {
1679 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1680 }
1681 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001682
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001683 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001684
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001685 /* Initialize the API struct. */
1686 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001687
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001688 buffer.len = pkt.size();
1689 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1690 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1691 if (buffer.arr == NULL) {
1692 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1693 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1694 }
1695 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1696
1697 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1698 if (err) {
1699 OPENOLT_LOG(ERROR, openolt_log_id, "Error sending packets via nni port %d, flow_id %d err %d\n", intf_id, key.flow_id, err);
1700 } else {
1701 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1702 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001703
1704 return Status::OK;
1705}
1706
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001707uint32_t GetPortNum_(uint32_t flow_id) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001708 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001709 uint32_t port_no = 0;
1710 std::map<uint32_t, uint32_t >::const_iterator it = flowid_to_port.find(flow_id);
1711 if (it != flowid_to_port.end()) {
1712 port_no = it->second;
1713 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001714 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001715 return port_no;
1716}
1717
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001718#define FLOW_LOG(level,msg,err) \
1719 do { \
1720 OPENOLT_LOG(level, openolt_log_id, "--------> %s (flow_id %d) err: %d <--------\n", msg, key.flow_id, err); \
1721 OPENOLT_LOG(level, openolt_log_id, "intf_id %d, onu_id %d, uni_id %d, port_no %u, cookie %"PRIu64"\n", \
1722 access_intf_id, onu_id, uni_id, port_no, cookie); \
1723 OPENOLT_LOG(level, openolt_log_id, "flow_type %s, queue_id %d, sched_id %d\n", flow_type.c_str(), \
1724 cfg.data.egress_qos.u.fixed_queue.queue_id, cfg.data.egress_qos.tm_sched.id); \
1725 OPENOLT_LOG(level, openolt_log_id, "Ingress(intfd_type %s, intf_id %d), Egress(intf_type %s, intf_id %d)\n", \
1726 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), cfg.data.ingress_intf.intf_id, \
1727 GET_FLOW_INTERFACE_TYPE(cfg.data.egress_intf.intf_type), cfg.data.egress_intf.intf_id); \
1728 OPENOLT_LOG(level, openolt_log_id, "classifier(o_vid %d, o_pbits %d, i_vid %d, i_pbits %d, ether type 0x%x)\n", \
1729 c_val.o_vid, c_val.o_pbits, c_val.i_vid, c_val.i_pbits, classifier.eth_type()); \
1730 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", \
1731 c_val.ip_proto, gemport_id, c_val.src_port, c_val.dst_port, GET_PKT_TAG_TYPE(c_val.pkt_tag_type)); \
1732 OPENOLT_LOG(level, openolt_log_id, "action(cmds_bitmask %s, o_vid %d, o_pbits %d, i_vid %d, i_pbits %d)\n\n", \
1733 get_flow_acton_command(a_val.cmds_bitmask), a_val.o_vid, a_val.o_pbits, a_val.i_vid, a_val.i_pbits); \
1734 } while(0)
1735
1736#define FLOW_PARAM_LOG() \
1737 do { \
1738 OPENOLT_LOG(INFO, openolt_log_id, "--------> flow comparison (now before) <--------\n"); \
1739 OPENOLT_LOG(INFO, openolt_log_id, "flow_id (%d %d)\n", \
1740 key.flow_id, flow_index); \
1741 OPENOLT_LOG(INFO, openolt_log_id, "onu_id (%d %lu)\n", \
1742 cfg.data.onu_id , get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)); \
1743 OPENOLT_LOG(INFO, openolt_log_id, "type (%d %lu)\n", \
1744 key.flow_type, get_flow_status(flow_index, flow_id_data[flowid][1], FLOW_TYPE)); \
1745 OPENOLT_LOG(INFO, openolt_log_id, "svc_port_id (%d %lu)\n", \
1746 cfg.data.svc_port_id, get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)); \
1747 OPENOLT_LOG(INFO, openolt_log_id, "priority (%d %lu)\n", \
1748 cfg.data.priority, get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)); \
1749 OPENOLT_LOG(INFO, openolt_log_id, "cookie (%lu %lu)\n", \
1750 cfg.data.cookie, get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)); \
1751 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf_type (%s %s)\n", \
1752 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), \
1753 GET_FLOW_INTERFACE_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE))); \
1754 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf id (%d %lu)\n", \
1755 cfg.data.ingress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)); \
1756 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_type (%d %lu)\n", \
1757 cfg.data.egress_intf.intf_type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)); \
1758 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_id (%d %lu)\n", \
1759 cfg.data.egress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)); \
1760 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_vid (%d %lu)\n", \
1761 c_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)); \
1762 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_pbits (%d %lu)\n", \
1763 c_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)); \
1764 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_vid (%d %lu)\n", \
1765 c_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)); \
1766 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_pbits (%d %lu)\n", \
1767 c_val.i_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)); \
1768 OPENOLT_LOG(INFO, openolt_log_id, "classifier ether_type (0x%x 0x%lx)\n", \
1769 c_val.ether_type , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)); \
1770 OPENOLT_LOG(INFO, openolt_log_id, "classifier ip_proto (%d %lu)\n", \
1771 c_val.ip_proto , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)); \
1772 OPENOLT_LOG(INFO, openolt_log_id, "classifier src_port (%d %lu)\n", \
1773 c_val.src_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)); \
1774 OPENOLT_LOG(INFO, openolt_log_id, "classifier dst_port (%d %lu)\n", \
1775 c_val.dst_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)); \
1776 OPENOLT_LOG(INFO, openolt_log_id, "classifier pkt_tag_type (%s %s)\n", \
1777 GET_PKT_TAG_TYPE(c_val.pkt_tag_type), \
1778 GET_PKT_TAG_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE))); \
1779 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos type (%d %lu)\n", \
1780 cfg.data.egress_qos.type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)); \
1781 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos queue_id (%d %lu)\n", \
1782 cfg.data.egress_qos.u.fixed_queue.queue_id, \
1783 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)); \
1784 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos sched_id (%d %lu)\n", \
1785 cfg.data.egress_qos.tm_sched.id, \
1786 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)); \
1787 OPENOLT_LOG(INFO, openolt_log_id, "classifier cmds_bitmask (%s %s)\n", \
1788 get_flow_acton_command(a_val.cmds_bitmask), \
1789 get_flow_acton_command(get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_CMDS_BITMASK))); \
1790 OPENOLT_LOG(INFO, openolt_log_id, "action o_vid (%d %lu)\n", \
1791 a_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)); \
1792 OPENOLT_LOG(INFO, openolt_log_id, "action i_vid (%d %lu)\n", \
1793 a_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)); \
1794 OPENOLT_LOG(INFO, openolt_log_id, "action o_pbits (%d %lu)\n", \
1795 a_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)); \
1796 OPENOLT_LOG(INFO, openolt_log_id, "action i_pbits (%d %lu)\n\n", \
1797 a_val.i_pbits, get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)); \
1798 } while(0)
1799
1800#define FLOW_CHECKER
1801//#define SHOW_FLOW_PARAM
1802
Craig Lutgen967a1d02018-11-27 10:41:51 -06001803Status 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 +00001804 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001805 int32_t alloc_id, int32_t network_intf_id,
1806 int32_t gemport_id, const ::openolt::Classifier& classifier,
Craig Lutgen967a1d02018-11-27 10:41:51 -06001807 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001808 bcmolt_flow_cfg cfg;
1809 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001810 int32_t o_vid = -1;
1811 bool single_tag = false;
1812 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001813 bcmolt_classifier c_val = { };
1814 bcmolt_action a_val = { };
1815 bcmolt_tm_queue_ref tm_val = { };
1816 int tm_qmp_id, tm_q_set_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001817
1818 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001819 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001820 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001821 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001822 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001823 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001824 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001825 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001826 }
1827
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001828 BCMOLT_CFG_INIT(&cfg, flow, key);
1829 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001830
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001831 if (access_intf_id >= 0 && network_intf_id >= 0) {
1832 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1833 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1834 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
1835 if (classifier.eth_type() == EAP_ETHER_TYPE || //EAPOL packet
1836 (classifier.ip_proto() == 17 && classifier.src_port() == 68 && classifier.dst_port() == 67)) { //DHCP packet
1837 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
1838 } else {
1839 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1840 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
1841 }
1842 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1843 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1844 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1845 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1846 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
1847 }
1848 } else {
1849 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1850 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
1851 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001852
Shad Ansari39739bc2018-09-13 21:38:37 +00001853 if (onu_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001854 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001855 }
1856 if (gemport_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001857 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001858 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001859 if (gemport_id >= 0 && port_no != 0) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001860 bcmos_fastlock_lock(&data_lock);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001861 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001862 port_to_flows[port_no].insert(key.flow_id);
1863 flowid_to_gemport[key.flow_id] = gemport_id;
1864 }
1865 else
1866 {
1867 flowid_to_port[key.flow_id] = port_no;
1868 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001869 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001870 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001871 if (priority_value >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001872 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
Shad Ansari39739bc2018-09-13 21:38:37 +00001873 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001874
1875 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001876 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001877 if (classifier.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001878 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_tpid 0x%04x\n", classifier.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05001879 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_tpid, classifier.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001880 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001881 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001882 if (classifier.o_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001883 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1884 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001885 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001886 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001887 if (classifier.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001888 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_tpid 0x%04x\n", classifier.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05001889 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_tpid, classifier.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001890 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001891 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001892 if (classifier.i_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001893 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1894 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001895 }
1896
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001897 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001898 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001899 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1900 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001901 }
1902
1903 /*
1904 if (classifier.dst_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001905 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_mac, classifier.dst_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001906 }
1907
1908 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001909 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001910 }
1911 */
1912
1913 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001914 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1915 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001916 }
1917
1918 /*
1919 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001920 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001921 }
1922
1923 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001924 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001925 }
1926 */
1927
1928 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001929 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1930 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001931 }
1932
1933 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001934 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1935 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001936 }
1937
1938 if (!classifier.pkt_tag_type().empty()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001939 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001940 if (classifier.pkt_tag_type().compare("untagged") == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001941 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001942 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001943 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001944 single_tag = true;
1945
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001946 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
1947 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001948 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001949 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001950
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001951 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
1952 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001953 }
1954 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001955 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001956 }
1957
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001958 if (cfg.data.egress_intf.intf_type != BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001959 const ::openolt::ActionCmd& cmd = action.cmd();
1960
1961 if (cmd.add_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001962 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1963 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001964 }
1965
1966 if (cmd.remove_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001967 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1968 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001969 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001970 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001971 if (cmd.trap_to_host()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001972 OPENOLT_LOG(INFO, openolt_log_id, "action trap-to-host\n");
Craig Lutgen19512312018-11-02 10:14:46 -05001973 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001974 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001975 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001976 if (action.o_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001977 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001978 o_vid = action.o_vid();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001979 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001980 }
1981
1982 if (action.o_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001983 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1984 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001985 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001986 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001987 if (action.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001988 OPENOLT_LOG(INFO, openolt_log_id, "action o_tpid=0x%04x\n", action.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05001989 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_tpid, action.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001990 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001991 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001992 if (action.i_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001993 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1994 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001995 }
1996
1997 if (action.i_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001998 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1999 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002000 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002001 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002002 if (action.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002003 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_tpid=0x%04x\n", action.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002004 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_tpid, action.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002005 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002006 */
2007 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002008 }
2009
Shad Ansari39739bc2018-09-13 21:38:37 +00002010 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002011 if(single_tag && ether_type == EAP_ETHER_TYPE) {
2012 tm_val.sched_id = (flow_type.compare(upstream) == 0) ? \
2013 get_default_tm_sched_id(network_intf_id, upstream) : \
2014 get_default_tm_sched_id(access_intf_id, downstream);
2015 tm_val.queue_id = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002016
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002017 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2018 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2019 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002020
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002021 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2022 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2023 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2024 } else {
2025 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
2026 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
2027
2028 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2029 // Queue 0 on DS subscriber scheduler
2030 tm_val.queue_id = 0;
2031
2032 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2033 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2034 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2035
2036 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2037 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2038 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2039
2040 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2041 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2042 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2043
2044 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2045 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2046 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2047 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2048
2049 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2050 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2051 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2052 }
2053 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2054 // NNI Scheduler ID
2055 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2056 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2057 // Queue 0 on NNI scheduler
2058 tm_val.queue_id = 0;
2059 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2060 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2061 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2062
2063 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2064 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2065 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2066
2067 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2068 /* Fetch TM QMP ID mapped to US NNI scheduler */
2069 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2070 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2071 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2072 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2073 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2074
2075 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2076 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2077 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2078 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002079 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002080 }
Shad Ansari06101952018-07-25 00:22:09 +00002081 }
2082
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002083 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
2084 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2085#ifdef FLOW_CHECKER
2086 //Flow Checker, To avoid duplicate flow.
2087 if (flow_id_counters != 0) {
2088 bool b_duplicate_flow = false;
2089 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2090 int flow_index = flow_id_data[flowid][0];
2091 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)) && \
2092 (key.flow_type == flow_id_data[flowid][1]) && \
2093 (cfg.data.svc_port_id == get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)) && \
2094 (cfg.data.priority == get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)) && \
2095 (cfg.data.cookie == get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)) && \
2096 (cfg.data.ingress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE)) && \
2097 (cfg.data.ingress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)) && \
2098 (cfg.data.egress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)) && \
2099 (cfg.data.egress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)) && \
2100 (c_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)) && \
2101 (c_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)) && \
2102 (c_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)) && \
2103 (c_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)) && \
2104 (c_val.ether_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)) && \
2105 (c_val.ip_proto == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)) && \
2106 (c_val.src_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)) && \
2107 (c_val.dst_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)) && \
2108 (c_val.pkt_tag_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE)) && \
2109 (cfg.data.egress_qos.type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)) && \
2110 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)) && \
2111 (cfg.data.egress_qos.tm_sched.id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)) && \
2112 (a_val.cmds_bitmask == get_flow_status(flowid, flow_id_data[flowid][1], ACTION_CMDS_BITMASK)) && \
2113 (a_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)) && \
2114 (a_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)) && \
2115 (a_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)) && \
2116 (a_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)) && \
2117 (cfg.data.state == get_flow_status(flowid, flow_id_data[flowid][1], STATE));
2118#ifdef SHOW_FLOW_PARAM
2119 // Flow Parameter
2120 FLOW_PARAM_LOG();
2121#endif
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002122
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002123 if (b_duplicate_flow) {
2124 FLOW_LOG(WARNING, "Flow duplicate", 0);
2125 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2126 }
2127 }
2128 }
2129#endif
2130
2131 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2132 if (err) {
2133 FLOW_LOG(ERROR, "Flow add failed", err);
2134 return bcm_to_grpc_err(err, "flow add failed");
2135 } else {
2136 FLOW_LOG(INFO, "Flow add ok", err);
2137 bcmos_fastlock_lock(&data_lock);
2138 flow_id_data[flow_id_counters][0] = key.flow_id;
2139 flow_id_data[flow_id_counters][1] = key.flow_type;
2140 flow_id_counters += 1;
2141 bcmos_fastlock_unlock(&data_lock, 0);
2142 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002143
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002144 return Status::OK;
2145}
2146
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002147Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2148
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002149 bcmolt_flow_cfg cfg;
2150 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002151
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002152 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002153 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002154 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002155 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002156 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002157 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002158 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002159 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002160 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2161 }
2162
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002163 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002164 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002165 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002166 flowid_to_gemport.erase(key.flow_id);
2167 port_to_flows[port_no].erase(key.flow_id);
2168 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2169 }
2170 else
2171 {
2172 flowid_to_port.erase(key.flow_id);
2173 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002174 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002175
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002176 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002177
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002178 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002179 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002180 OPENOLT_LOG(ERROR, openolt_log_id, "Error %d while removing flow %d, %s\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04002181 err, flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002182 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2183 }
2184
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002185 bcmos_fastlock_lock(&data_lock);
2186 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2187 if (flow_id_data[flowid][0] == flow_id && flow_id_data[flowid][1] == key.flow_type) {
2188 flow_id_counters -= 1;
2189 for (int i=flowid; i < flow_id_counters; i++) {
2190 flow_id_data[i][0] = flow_id_data[i + 1][0];
2191 flow_id_data[i][1] = flow_id_data[i + 1][1];
2192 }
2193 break;
2194 }
2195 }
2196 bcmos_fastlock_unlock(&data_lock, 0);
2197
2198 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002199 return Status::OK;
2200}
2201
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002202bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2203 bcmos_errno err;
2204 bcmolt_tm_sched_cfg tm_sched_cfg;
2205 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2206 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2207
Jason Huangbf45ffb2019-10-30 17:29:02 +08002208 //check TM scheduler has configured or not
2209 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2210 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
2211 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
2212 if (err) {
2213 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query TM scheduler\n");
2214 return err;
2215 }
2216 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2217 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2218 return BCM_ERR_OK;
2219 }
2220
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002221 // bcmbal_tm_sched_owner
2222 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2223
2224 /**< The output of the tm_sched object instance */
2225 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2226
2227 if (direction.compare(upstream) == 0) {
2228 // In upstream it is NNI scheduler
2229 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2230 } else if (direction.compare(downstream) == 0) {
2231 // In downstream it is PON scheduler
2232 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2233 }
2234
2235 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2236
2237 // bcmbal_tm_sched_type
2238 // set the deafult policy to strict priority
2239 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2240
2241 // num_priorities: Max number of strict priority scheduling elements
2242 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
2243
2244 // bcmbal_tm_shaping
2245 uint32_t cir = 1000000;
2246 uint32_t pir = 1000000;
2247 uint32_t burst = 65536;
2248 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in %s pir=%u, burst=%u\n",
2249 direction.c_str(), pir, burst);
2250 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2251 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2252 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2253 // BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2254 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2255 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
2256
2257 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2258 if (err) {
2259 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err %d\n", \
2260 direction.c_str(), tm_sched_key.id, intf_id, err);
2261 return err;
2262 }
2263
2264 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2265 direction.c_str(), tm_sched_key.id, intf_id);
2266 return BCM_ERR_OK;
2267}
2268
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002269bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
2270 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2271 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002272
2273 bcmos_errno err;
2274
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002275 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002276 bcmolt_tm_sched_cfg tm_sched_cfg;
2277 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2278 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002279
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002280 // bcmbal_tm_sched_owner
2281 // In downstream it is sub_term scheduler
2282 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002283
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002284 /**< The output of the tm_sched object instance */
2285 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002286
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002287 // bcmbal_tm_sched_parent
2288 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2289 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2290 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_param.u.priority.priority, priority);
2291 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
2292 be achieved using the' virtual' type of attachment.
2293 tm_sched_owner.u.sub_term.intf_id = intf_id;
2294 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2295 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002296
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002297 // bcmbal_tm_sched_type
2298 // set the deafult policy to strict priority
2299 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002300
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002301 // num_priorities: Max number of strict priority scheduling elements
2302 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002303
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002304 // bcmbal_tm_shaping
2305 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2306 uint32_t cir = tf_sh_info.cir();
2307 uint32_t pir = tf_sh_info.pir();
2308 uint32_t burst = tf_sh_info.pbs();
2309 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2310 cir, pir, burst);
2311 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2312 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2313 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2314 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2315 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2316 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002317 }
2318
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002319 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002320 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002321 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
2322intf_id %d, onu_id %d, uni_id %d, port_no %u\n", tm_sched_key.id, intf_id, onu_id, \
2323 uni_id, port_no);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002324 return err;
2325 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002326 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2327uni_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 -08002328
2329 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002330 bcmolt_itupon_alloc_cfg cfg;
2331 bcmolt_itupon_alloc_key key = { };
2332 key.pon_ni = intf_id;
2333 key.alloc_id = alloc_id;
2334 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
2335 int pir_bw = tf_sh_info.pir();
2336 int cir_bw = tf_sh_info.cir();
2337 //offset to match bandwidth granularity
2338 int offset_pir_bw = pir_bw%bw_granularity;
2339 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002340
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002341 pir_bw = pir_bw - offset_pir_bw;
2342 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002343
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002344 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002345
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002346 switch (additional_bw) {
2347 case 2: //AdditionalBW_BestEffort
2348 if (pir_bw == 0) {
2349 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2350%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2351 } else if (pir_bw < cir_bw) {
2352 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2353bandwidth (%d)\n", pir_bw, cir_bw);
2354 return BCM_ERR_PARM;
2355 } else if (pir_bw == cir_bw) {
2356 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2357bandwidth for additional bandwidth eligibility of type best_effort\n");
2358 return BCM_ERR_PARM;
2359 }
2360 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2361 break;
2362 case 1: //AdditionalBW_NA
2363 if (pir_bw == 0) {
2364 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2365%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2366 return BCM_ERR_PARM;
2367 } else if (cir_bw == 0) {
2368 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2369additional bandwidth eligibility of type Non-Assured (NA)\n");
2370 return BCM_ERR_PARM;
2371 } else if (pir_bw < cir_bw) {
2372 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2373bandwidth (%d)\n", pir_bw, cir_bw);
2374 return BCM_ERR_PARM;
2375 } else if (pir_bw == cir_bw) {
2376 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2377bandwidth for additional bandwidth eligibility of type non_assured\n");
2378 return BCM_ERR_PARM;
2379 }
2380 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2381 break;
2382 case 0: //AdditionalBW_None
2383 if (pir_bw == 0) {
2384 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
238516000 bytes/sec\n");
2386 return BCM_ERR_PARM;
2387 } else if (cir_bw == 0) {
2388 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2389for additional bandwidth eligibility of type None\n");
2390 return BCM_ERR_PARM;
2391 } else if (pir_bw > cir_bw) {
2392 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2393for additional bandwidth eligibility of type None\n");
2394 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2395bandwidth in None eligibility\n", pir_bw);
2396 cir_bw = pir_bw;
2397 } else if (pir_bw < cir_bw) {
2398 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2399bandwidth (%d)\n", pir_bw, cir_bw);
2400 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2401bandwidth in None eligibility\n", pir_bw);
2402 cir_bw = pir_bw;
2403 }
2404 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2405 break;
2406 default:
2407 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002408 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002409 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2410 in a fine granularity. */
2411 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2412 /* Fixed Bandwidth with no critical requirement of shaping */
2413 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2414 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2415 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2416 /* Maximum allocated bandwidth allowed for this alloc ID */
2417 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2418 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2419 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
2420 for skipped allocations during quiet window */
2421 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2422 /**< Allocation Profile index for CBR non-RT Bandwidth */
2423 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2424 /**< Allocation Profile index for CBR RT Bandwidth */
2425 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2426 /**< Alloc ID Weight used in case of Extended DBA mode */
2427 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2428 /**< Alloc ID Priority used in case of Extended DBA mode */
2429 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2430 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002431
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002432 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002433 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002434 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2435port_no %u, alloc_id %d, err %d\n", intf_id, onu_id,uni_id,port_no,alloc_id, err);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002436 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002437 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002438 OPENOLT_LOG(INFO, openolt_log_id, "Create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d, port_no %u, \
2439alloc_id %d\n", intf_id,onu_id,uni_id,port_no,alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002440 }
2441
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002442 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002443}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002444
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002445Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2446 uint32_t intf_id = traffic_scheds->intf_id();
2447 uint32_t onu_id = traffic_scheds->onu_id();
2448 uint32_t uni_id = traffic_scheds->uni_id();
2449 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002450 std::string direction;
2451 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002452 tech_profile::SchedulerConfig sched_config;
2453 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002454 uint32_t priority;
2455 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002456 tech_profile::SchedulingPolicy sched_policy;
2457 tech_profile::TrafficShapingInfo traffic_shaping_info;
2458 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002459
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002460 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2461 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002462
2463 direction = GetDirection(traffic_sched.direction());
2464 if (direction.compare("direction-not-supported") == 0)
2465 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2466
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002467 alloc_id = traffic_sched.alloc_id();
2468 sched_config = traffic_sched.scheduler();
2469 additional_bw = sched_config.additional_bw();
2470 priority = sched_config.priority();
2471 weight = sched_config.weight();
2472 sched_policy = sched_config.sched_policy();
2473 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2474 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2475 sched_policy, traffic_shaping_info);
2476 if (err) {
2477 return bcm_to_grpc_err(err, "Failed to create scheduler");
2478 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002479 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002480 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002481}
Jonathan Davis70c21812018-07-19 15:32:10 -04002482
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002483bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002484
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002485 bcmos_errno err;
Jonathan Davis70c21812018-07-19 15:32:10 -04002486
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002487 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002488 bcmolt_itupon_alloc_cfg cfg;
2489 bcmolt_itupon_alloc_key key = { };
2490 key.pon_ni = intf_id;
2491 key.alloc_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002492
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002493 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
2494 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2495 if (err) {
2496 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler sched, direction = %s, intf_id %d, alloc_id %d, err %d\n", \
2497 direction.c_str(), intf_id, alloc_id, err);
2498 return err;
2499 }
2500 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, intf_id %d, alloc_id %d\n", \
2501 direction.c_str(), intf_id, alloc_id);
2502 } else if (direction == downstream) {
2503 bcmolt_tm_sched_cfg cfg;
2504 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002505
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002506 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
2507 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2508 } else {
2509 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2510 return BCM_ERR_OK;
2511 }
2512 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2513 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2514 if (err) {
2515 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, id %d, intf_id %d, onu_id %d\n", \
2516 direction.c_str(), key.id, intf_id, onu_id);
2517 return err;
2518 }
2519 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n", \
2520 direction.c_str(), key.id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002521 }
2522
2523 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002524 return BCM_ERR_OK;
2525}
2526
2527Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2528 uint32_t intf_id = traffic_scheds->intf_id();
2529 uint32_t onu_id = traffic_scheds->onu_id();
2530 uint32_t uni_id = traffic_scheds->uni_id();
2531 std::string direction;
2532 bcmos_errno err;
2533
2534 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2535 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002536
2537 direction = GetDirection(traffic_sched.direction());
2538 if (direction.compare("direction-not-supported") == 0)
2539 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2540
2541 int alloc_id = traffic_sched.alloc_id();
2542 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002543 if (err) {
2544 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2545 }
2546 }
2547 return Status::OK;
2548}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002549
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002550bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2551 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002552 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002553 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2554 bcmolt_tm_qmp_key tm_qmp_key;
2555 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002556
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002557 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2558 if (tm_qmp_id == -1) {
2559 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 -08002560 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002561
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002562 tm_qmp_key.id = tm_qmp_id;
2563 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2564 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2565 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002566
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002567 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2568 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2569 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
2570 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2571 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002572
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002573 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002574 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002575 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, id %d\n", \
2576 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002577 return err;
2578 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002579
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002580 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2581 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002582 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002583}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002584
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002585bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2586 bcmos_errno err;
2587 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2588 bcmolt_tm_qmp_key tm_qmp_key;
2589 tm_qmp_key.id = tm_qmp_id;
2590
2591 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2592 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2593 if (err) {
2594 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, id %d\n", \
2595 tm_qmp_key.id);
2596 return err;
2597 }
2598
2599 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2600 tm_qmp_key.id);
2601 return BCM_ERR_OK;
2602}
2603
2604bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2605 bcmos_errno err;
2606
2607 /* Create 4 Queues on given PON/NNI scheduler */
2608 for (int queue_id = 0; queue_id < 4; queue_id++) {
2609 bcmolt_tm_queue_cfg tm_queue_cfg;
2610 bcmolt_tm_queue_key tm_queue_key = {};
2611 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2612 tm_queue_key.id = queue_id;
2613 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE)
2614 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2615 else
2616 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2617
2618 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2619 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2620 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2621
2622 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2623 if (err) {
2624 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s tm queue, id %d, sched_id %d, tm_q_set_id %d\n", \
2625 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2626 return err;
2627 }
2628
2629 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2630 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2631 }
2632 return BCM_ERR_OK;
2633}
2634
2635bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t priority,
2636 uint32_t gemport_id) {
2637 bcmos_errno err;
2638 bcmolt_tm_queue_cfg cfg;
2639 bcmolt_tm_queue_key key = { };
2640 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
2641gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
2642
2643 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2644 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2645
2646 if (priority > 7) {
2647 return BCM_ERR_RANGE;
2648 }
2649
2650 /* FIXME: The upstream queues have to be created once only.
2651 The upstream queues on the NNI scheduler are shared by all subscribers.
2652 When the first scheduler comes in, the queues get created, and are re-used by all others.
2653 Also, these queues should be present until the last subscriber exits the system.
2654 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2655
2656 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2657 for each GEM in TECH PROFILE */
2658 key.id = queue_id_list[priority];
2659
2660 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2661 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2662 key.id = 0;
2663 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2664 }
2665 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2666 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2667 }
2668 else {
2669 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2670 }
2671
2672 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2673
2674 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2675 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2676
2677 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2678 if (err) {
2679 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, id %d, \
2680sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err %d\n", \
2681 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, err);
2682 return err;
2683 }
2684
2685 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2686intf_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);
2687 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002688}
2689
2690Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2691 uint32_t intf_id = traffic_queues->intf_id();
2692 uint32_t onu_id = traffic_queues->onu_id();
2693 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002694 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002695 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002696 bcmos_errno err;
2697
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002698 qos_type = (traffic_queues->traffic_queues_size() > 1) ? \
2699 BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE : BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
2700
2701 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2702 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2703 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2704 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2705 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2706
2707 direction = GetDirection(traffic_queue.direction());
2708 if (direction.compare("direction-not-supported") == 0)
2709 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2710
2711 queues_priority_q[i] = traffic_queue.priority();
2712 queues_pbit_map[i] = traffic_queue.pbit_map();
2713 }
2714
2715 std::vector<uint32_t> tmq_map_profile(8, 0);
2716 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2717 queues_priority_q, COUNT_OF(queues_priority_q));
2718 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2719 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2720
2721 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2722 if (tm_qmp_id == -1) {
2723 CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2724 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2725 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2726 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2727 }
2728 }
2729
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002730 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2731 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002732
2733 direction = GetDirection(traffic_queue.direction());
2734 if (direction.compare("direction-not-supported") == 0)
2735 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2736
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002737 err = CreateQueue(direction, intf_id, onu_id, uni_id, traffic_queue.priority(), traffic_queue.gemport_id());
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002738
Girish Gowdruf26cf882019-05-01 23:47:58 -07002739 // If the queue exists already, lets not return failure and break the loop.
2740 if (err && err != BCM_ERR_ALREADY) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002741 return bcm_to_grpc_err(err, "Failed to create queue");
2742 }
2743 }
2744 return Status::OK;
2745}
2746
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002747bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t priority,
2748 uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002749 bcmolt_tm_queue_cfg cfg;
2750 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002751 bcmos_errno err;
2752
2753 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002754 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
2755 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2756 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002757 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002758 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 -08002759 return BCM_ERR_OK;
2760 }
2761 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002762 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2763 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002764 return BCM_ERR_OK;
2765 }
2766
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002767 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2768 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2769 // Reset the queue id to 0 when using fixed queue.
2770 key.id = 0;
2771 }
2772 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2773 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2774 }
2775 else {
2776 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2777 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002778
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002779 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2780 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002781 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002782 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, id %d, sched_id %d, \
2783tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d\n",
2784 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 -08002785 return err;
2786 }
2787
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002788 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2789intf_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 -08002790
2791 return BCM_ERR_OK;
2792}
2793
2794Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2795 uint32_t intf_id = traffic_queues->intf_id();
2796 uint32_t onu_id = traffic_queues->onu_id();
2797 uint32_t uni_id = traffic_queues->uni_id();
2798 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002799 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002800 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002801 bcmos_errno err;
2802
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002803 qos_type = (traffic_queues->traffic_queues_size() > 1) ? \
2804 BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE : BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
2805
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002806 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2807 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002808
2809 direction = GetDirection(traffic_queue.direction());
2810 if (direction.compare("direction-not-supported") == 0)
2811 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2812
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002813 err = RemoveQueue(direction, intf_id, onu_id, uni_id, traffic_queue.priority(), traffic_queue.gemport_id());
2814 if (err) {
2815 return bcm_to_grpc_err(err, "Failed to remove queue");
2816 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002817 }
2818
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002819 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))) {
2820 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2821 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2822
2823 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2824 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
2825 RemoveTrafficQueueMappingProfile(tm_qmp_id);
2826 }
2827 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002828 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002829}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002830
2831Status check_connection() {
2832 int maxTrials = 60;
2833 while (!bcmolt_api_conn_mgr_is_connected(dev_id)) {
2834 sleep(1);
2835 if (--maxTrials == 0)
2836 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check connection failed");
2837 else
2838 OPENOLT_LOG(INFO, openolt_log_id, "waiting for daemon connection ...\n");
2839 }
2840 OPENOLT_LOG(INFO, openolt_log_id, "daemon is connected\n");
2841 return Status::OK;
2842}
2843
2844Status check_bal_ready() {
2845 bcmos_errno err;
2846 int maxTrials = 30;
2847 bcmolt_olt_cfg olt_cfg = { };
2848 bcmolt_olt_key olt_key = { };
2849
2850 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
2851 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
2852
2853 while (olt_cfg.data.bal_state != BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY) {
2854 if (--maxTrials == 0)
2855 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check bal ready failed");
2856 sleep(5);
2857 #ifdef TEST_MODE
2858 // It is impossible to mock the setting of olt_cfg.data.bal_state because
2859 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
2860 // set the olt_cfg.data.bal_state. So a new stub function is created and address
2861 // of olt_cfg is passed. This is one-of case where we need to add specific
2862 // code in product code.
2863 if (bcmolt_cfg_get_stub(dev_id, &olt_cfg)) {
2864 #else
2865 if (bcmolt_cfg_get(dev_id, &olt_cfg.hdr)) {
2866 #endif
2867 continue;
2868 }
2869 else
2870 OPENOLT_LOG(INFO, openolt_log_id, "waiting for BAL ready ...\n");
2871 }
2872
2873 OPENOLT_LOG(INFO, openolt_log_id, "BAL is ready\n");
2874 return Status::OK;
2875}