Lines Matching full:sparx5
2 /* Microchip Sparx5 Switch driver
44 static int sparx5_mact_get_status(struct sparx5 *sparx5) in sparx5_mact_get_status() argument
46 return spx5_rd(sparx5, LRN_COMMON_ACCESS_CTRL); in sparx5_mact_get_status()
49 static int sparx5_mact_wait_for_completion(struct sparx5 *sparx5) in sparx5_mact_wait_for_completion() argument
54 sparx5, val, in sparx5_mact_wait_for_completion()
59 static void sparx5_mact_select(struct sparx5 *sparx5, in sparx5_mact_select() argument
76 spx5_wr(mach, sparx5, LRN_MAC_ACCESS_CFG_0); in sparx5_mact_select()
77 spx5_wr(macl, sparx5, LRN_MAC_ACCESS_CFG_1); in sparx5_mact_select()
80 int sparx5_mact_learn(struct sparx5 *sparx5, int pgid, in sparx5_mact_learn() argument
83 const struct sparx5_consts *consts = sparx5->data->consts; in sparx5_mact_learn()
95 mutex_lock(&sparx5->lock); in sparx5_mact_learn()
97 sparx5_mact_select(sparx5, mac, vid); in sparx5_mact_learn()
104 sparx5, LRN_MAC_ACCESS_CFG_2); in sparx5_mact_learn()
105 spx5_wr(0, sparx5, LRN_MAC_ACCESS_CFG_3); in sparx5_mact_learn()
110 sparx5, LRN_COMMON_ACCESS_CTRL); in sparx5_mact_learn()
112 ret = sparx5_mact_wait_for_completion(sparx5); in sparx5_mact_learn()
114 mutex_unlock(&sparx5->lock); in sparx5_mact_learn()
122 struct sparx5 *sparx5 = port->sparx5; in sparx5_mc_unsync() local
124 return sparx5_mact_forget(sparx5, addr, port->pvid); in sparx5_mc_unsync()
130 struct sparx5 *sparx5 = port->sparx5; in sparx5_mc_sync() local
132 return sparx5_mact_learn(sparx5, sparx5_get_pgid(sparx5, PGID_CPU), in sparx5_mc_sync()
136 static int sparx5_mact_get(struct sparx5 *sparx5, in sparx5_mact_get() argument
143 cfg2 = spx5_rd(sparx5, LRN_MAC_ACCESS_CFG_2); in sparx5_mact_get()
145 mach = spx5_rd(sparx5, LRN_MAC_ACCESS_CFG_0); in sparx5_mact_get()
146 macl = spx5_rd(sparx5, LRN_MAC_ACCESS_CFG_1); in sparx5_mact_get()
161 bool sparx5_mact_getnext(struct sparx5 *sparx5, in sparx5_mact_getnext() argument
167 mutex_lock(&sparx5->lock); in sparx5_mact_getnext()
169 sparx5_mact_select(sparx5, mac, *vid); in sparx5_mact_getnext()
173 sparx5, LRN_SCAN_NEXT_CFG); in sparx5_mact_getnext()
177 sparx5, LRN_COMMON_ACCESS_CTRL); in sparx5_mact_getnext()
179 ret = sparx5_mact_wait_for_completion(sparx5); in sparx5_mact_getnext()
181 ret = sparx5_mact_get(sparx5, mac, vid, &cfg2); in sparx5_mact_getnext()
186 mutex_unlock(&sparx5->lock); in sparx5_mact_getnext()
191 int sparx5_mact_find(struct sparx5 *sparx5, in sparx5_mact_find() argument
197 mutex_lock(&sparx5->lock); in sparx5_mact_find()
199 sparx5_mact_select(sparx5, mac, vid); in sparx5_mact_find()
204 sparx5, LRN_COMMON_ACCESS_CTRL); in sparx5_mact_find()
206 ret = sparx5_mact_wait_for_completion(sparx5); in sparx5_mact_find()
208 cfg2 = spx5_rd(sparx5, LRN_MAC_ACCESS_CFG_2); in sparx5_mact_find()
215 mutex_unlock(&sparx5->lock); in sparx5_mact_find()
220 int sparx5_mact_forget(struct sparx5 *sparx5, in sparx5_mact_forget() argument
225 mutex_lock(&sparx5->lock); in sparx5_mact_forget()
227 sparx5_mact_select(sparx5, mac, vid); in sparx5_mact_forget()
232 sparx5, LRN_COMMON_ACCESS_CTRL); in sparx5_mact_forget()
234 ret = sparx5_mact_wait_for_completion(sparx5); in sparx5_mact_forget()
236 mutex_unlock(&sparx5->lock); in sparx5_mact_forget()
241 static struct sparx5_mact_entry *alloc_mact_entry(struct sparx5 *sparx5, in alloc_mact_entry() argument
247 mact_entry = devm_kzalloc(sparx5->dev, in alloc_mact_entry()
258 static struct sparx5_mact_entry *find_mact_entry(struct sparx5 *sparx5, in find_mact_entry() argument
265 mutex_lock(&sparx5->mact_lock); in find_mact_entry()
266 list_for_each_entry(mact_entry, &sparx5->mact_entries, list) { in find_mact_entry()
274 mutex_unlock(&sparx5->mact_lock); in find_mact_entry()
291 int sparx5_add_mact_entry(struct sparx5 *sparx5, in sparx5_add_mact_entry() argument
300 ret = sparx5_mact_find(sparx5, addr, vid, &cfg2); in sparx5_add_mact_entry()
310 mact_entry = find_mact_entry(sparx5, addr, vid, portno); in sparx5_add_mact_entry()
317 mact_entry = alloc_mact_entry(sparx5, addr, vid, portno); in sparx5_add_mact_entry()
321 mutex_lock(&sparx5->mact_lock); in sparx5_add_mact_entry()
322 list_add_tail(&mact_entry->list, &sparx5->mact_entries); in sparx5_add_mact_entry()
323 mutex_unlock(&sparx5->mact_lock); in sparx5_add_mact_entry()
326 ret = sparx5_mact_learn(sparx5, portno, addr, vid); in sparx5_add_mact_entry()
338 int sparx5_del_mact_entry(struct sparx5 *sparx5, in sparx5_del_mact_entry() argument
347 mutex_lock(&sparx5->mact_lock); in sparx5_del_mact_entry()
348 list_for_each_entry_safe(mact_entry, tmp, &sparx5->mact_entries, in sparx5_del_mact_entry()
352 sparx5_mact_forget(sparx5, addr, mact_entry->vid); in sparx5_del_mact_entry()
355 devm_kfree(sparx5->dev, mact_entry); in sparx5_del_mact_entry()
358 mutex_unlock(&sparx5->mact_lock); in sparx5_del_mact_entry()
363 static void sparx5_mact_handle_entry(struct sparx5 *sparx5, in sparx5_mact_handle_entry() argument
376 if (port >= sparx5->data->consts->n_ports) in sparx5_mact_handle_entry()
379 if (!test_bit(port, sparx5->bridge_mask)) in sparx5_mact_handle_entry()
382 mutex_lock(&sparx5->mact_lock); in sparx5_mact_handle_entry()
383 list_for_each_entry(mact_entry, &sparx5->mact_entries, list) { in sparx5_mact_handle_entry()
389 dev_warn(sparx5->dev, "Entry move: %d -> %d\n", in sparx5_mact_handle_entry()
398 mutex_unlock(&sparx5->mact_lock); in sparx5_mact_handle_entry()
406 mact_entry = alloc_mact_entry(sparx5, mac, vid, port); in sparx5_mact_handle_entry()
411 mutex_lock(&sparx5->mact_lock); in sparx5_mact_handle_entry()
412 list_add_tail(&mact_entry->list, &sparx5->mact_entries); in sparx5_mact_handle_entry()
413 mutex_unlock(&sparx5->mact_lock); in sparx5_mact_handle_entry()
418 mac, vid, sparx5->ports[port]->ndev, in sparx5_mact_handle_entry()
425 struct sparx5 *sparx5 = container_of(del_work, struct sparx5, in sparx5_mact_pull_work() local
434 mutex_lock(&sparx5->mact_lock); in sparx5_mact_pull_work()
435 list_for_each_entry(mact_entry, &sparx5->mact_entries, list) in sparx5_mact_pull_work()
437 mutex_unlock(&sparx5->mact_lock); in sparx5_mact_pull_work()
443 mutex_lock(&sparx5->lock); in sparx5_mact_pull_work()
444 sparx5_mact_select(sparx5, mac, vid); in sparx5_mact_pull_work()
446 sparx5, LRN_SCAN_NEXT_CFG); in sparx5_mact_pull_work()
450 sparx5, LRN_COMMON_ACCESS_CTRL); in sparx5_mact_pull_work()
451 ret = sparx5_mact_wait_for_completion(sparx5); in sparx5_mact_pull_work()
453 ret = sparx5_mact_get(sparx5, mac, &vid, &cfg2); in sparx5_mact_pull_work()
454 mutex_unlock(&sparx5->lock); in sparx5_mact_pull_work()
456 sparx5_mact_handle_entry(sparx5, mac, vid, cfg2); in sparx5_mact_pull_work()
459 mutex_lock(&sparx5->mact_lock); in sparx5_mact_pull_work()
460 list_for_each_entry_safe(mact_entry, tmp, &sparx5->mact_entries, in sparx5_mact_pull_work()
468 sparx5->ports[mact_entry->port]->ndev, in sparx5_mact_pull_work()
472 devm_kfree(sparx5->dev, mact_entry); in sparx5_mact_pull_work()
474 mutex_unlock(&sparx5->mact_lock); in sparx5_mact_pull_work()
476 queue_delayed_work(sparx5->mact_queue, &sparx5->mact_work, in sparx5_mact_pull_work()
480 void sparx5_set_ageing(struct sparx5 *sparx5, int msecs) in sparx5_set_ageing() argument
488 sparx5, in sparx5_set_ageing()
492 void sparx5_mact_init(struct sparx5 *sparx5) in sparx5_mact_init() argument
494 mutex_init(&sparx5->lock); in sparx5_mact_init()
499 sparx5, LRN_COMMON_ACCESS_CTRL); in sparx5_mact_init()
501 if (sparx5_mact_wait_for_completion(sparx5) != 0) in sparx5_mact_init()
502 dev_warn(sparx5->dev, "MAC flush error\n"); in sparx5_mact_init()
504 sparx5_set_ageing(sparx5, BR_DEFAULT_AGEING_TIME / HZ * 1000); in sparx5_mact_init()