Skip to content

Commit d520d58

Browse files
committed
Merge branch 'mlxsw-SPAN-cleanups'
Jiri Pirko says: ==================== mlxsw: SPAN cleanups In patch one of this short series, a misplaced pointer star is moved to the correct place. In the second patch, we observe that if SPAN entries carry their reference count anyway, it's redundant to also carry a "used" flag. In the third patch, SPAN support code is moved to a separate module. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 439ccd8 + a629ef2 commit d520d58

File tree

6 files changed

+433
-351
lines changed

6 files changed

+433
-351
lines changed

drivers/net/ethernet/mellanox/mlxsw/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \
2020
spectrum_cnt.o spectrum_fid.o \
2121
spectrum_ipip.o spectrum_acl_flex_actions.o \
2222
spectrum_mr.o spectrum_mr_tcam.o \
23-
spectrum_qdisc.o
23+
spectrum_qdisc.o spectrum_span.o
2424
mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB) += spectrum_dcb.o
2525
mlxsw_spectrum-$(CONFIG_NET_DEVLINK) += spectrum_dpipe.o
2626
obj-$(CONFIG_MLXSW_MINIMAL) += mlxsw_minimal.o

drivers/net/ethernet/mellanox/mlxsw/spectrum.c

Lines changed: 1 addition & 321 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
#include "spectrum_cnt.h"
7272
#include "spectrum_dpipe.h"
7373
#include "spectrum_acl_flex_actions.h"
74+
#include "spectrum_span.h"
7475
#include "../mlxfw/mlxfw.h"
7576

7677
#define MLXSW_FWREV_MAJOR 13
@@ -487,327 +488,6 @@ static int mlxsw_sp_base_mac_get(struct mlxsw_sp *mlxsw_sp)
487488
return 0;
488489
}
489490

490-
static int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
491-
{
492-
int i;
493-
494-
if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_SPAN))
495-
return -EIO;
496-
497-
mlxsw_sp->span.entries_count = MLXSW_CORE_RES_GET(mlxsw_sp->core,
498-
MAX_SPAN);
499-
mlxsw_sp->span.entries = kcalloc(mlxsw_sp->span.entries_count,
500-
sizeof(struct mlxsw_sp_span_entry),
501-
GFP_KERNEL);
502-
if (!mlxsw_sp->span.entries)
503-
return -ENOMEM;
504-
505-
for (i = 0; i < mlxsw_sp->span.entries_count; i++)
506-
INIT_LIST_HEAD(&mlxsw_sp->span.entries[i].bound_ports_list);
507-
508-
return 0;
509-
}
510-
511-
static void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
512-
{
513-
int i;
514-
515-
for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
516-
struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
517-
518-
WARN_ON_ONCE(!list_empty(&curr->bound_ports_list));
519-
}
520-
kfree(mlxsw_sp->span.entries);
521-
}
522-
523-
static struct mlxsw_sp_span_entry *
524-
mlxsw_sp_span_entry_create(struct mlxsw_sp_port *port)
525-
{
526-
struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
527-
struct mlxsw_sp_span_entry *span_entry;
528-
char mpat_pl[MLXSW_REG_MPAT_LEN];
529-
u8 local_port = port->local_port;
530-
int index;
531-
int i;
532-
int err;
533-
534-
/* find a free entry to use */
535-
index = -1;
536-
for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
537-
if (!mlxsw_sp->span.entries[i].used) {
538-
index = i;
539-
span_entry = &mlxsw_sp->span.entries[i];
540-
break;
541-
}
542-
}
543-
if (index < 0)
544-
return NULL;
545-
546-
/* create a new port analayzer entry for local_port */
547-
mlxsw_reg_mpat_pack(mpat_pl, index, local_port, true);
548-
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
549-
if (err)
550-
return NULL;
551-
552-
span_entry->used = true;
553-
span_entry->id = index;
554-
span_entry->ref_count = 1;
555-
span_entry->local_port = local_port;
556-
return span_entry;
557-
}
558-
559-
static void mlxsw_sp_span_entry_destroy(struct mlxsw_sp *mlxsw_sp,
560-
struct mlxsw_sp_span_entry *span_entry)
561-
{
562-
u8 local_port = span_entry->local_port;
563-
char mpat_pl[MLXSW_REG_MPAT_LEN];
564-
int pa_id = span_entry->id;
565-
566-
mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, false);
567-
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
568-
span_entry->used = false;
569-
}
570-
571-
struct mlxsw_sp_span_entry *
572-
mlxsw_sp_span_entry_find(struct mlxsw_sp *mlxsw_sp, u8 local_port)
573-
{
574-
int i;
575-
576-
for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
577-
struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
578-
579-
if (curr->used && curr->local_port == local_port)
580-
return curr;
581-
}
582-
return NULL;
583-
}
584-
585-
static struct mlxsw_sp_span_entry
586-
*mlxsw_sp_span_entry_get(struct mlxsw_sp_port *port)
587-
{
588-
struct mlxsw_sp_span_entry *span_entry;
589-
590-
span_entry = mlxsw_sp_span_entry_find(port->mlxsw_sp,
591-
port->local_port);
592-
if (span_entry) {
593-
/* Already exists, just take a reference */
594-
span_entry->ref_count++;
595-
return span_entry;
596-
}
597-
598-
return mlxsw_sp_span_entry_create(port);
599-
}
600-
601-
static int mlxsw_sp_span_entry_put(struct mlxsw_sp *mlxsw_sp,
602-
struct mlxsw_sp_span_entry *span_entry)
603-
{
604-
WARN_ON(!span_entry->ref_count);
605-
if (--span_entry->ref_count == 0)
606-
mlxsw_sp_span_entry_destroy(mlxsw_sp, span_entry);
607-
return 0;
608-
}
609-
610-
static bool mlxsw_sp_span_is_egress_mirror(struct mlxsw_sp_port *port)
611-
{
612-
struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
613-
struct mlxsw_sp_span_inspected_port *p;
614-
int i;
615-
616-
for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
617-
struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
618-
619-
list_for_each_entry(p, &curr->bound_ports_list, list)
620-
if (p->local_port == port->local_port &&
621-
p->type == MLXSW_SP_SPAN_EGRESS)
622-
return true;
623-
}
624-
625-
return false;
626-
}
627-
628-
static int mlxsw_sp_span_mtu_to_buffsize(const struct mlxsw_sp *mlxsw_sp,
629-
int mtu)
630-
{
631-
return mlxsw_sp_bytes_cells(mlxsw_sp, mtu * 5 / 2) + 1;
632-
}
633-
634-
static int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu)
635-
{
636-
struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
637-
char sbib_pl[MLXSW_REG_SBIB_LEN];
638-
int err;
639-
640-
/* If port is egress mirrored, the shared buffer size should be
641-
* updated according to the mtu value
642-
*/
643-
if (mlxsw_sp_span_is_egress_mirror(port)) {
644-
u32 buffsize = mlxsw_sp_span_mtu_to_buffsize(mlxsw_sp, mtu);
645-
646-
mlxsw_reg_sbib_pack(sbib_pl, port->local_port, buffsize);
647-
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
648-
if (err) {
649-
netdev_err(port->dev, "Could not update shared buffer for mirroring\n");
650-
return err;
651-
}
652-
}
653-
654-
return 0;
655-
}
656-
657-
static struct mlxsw_sp_span_inspected_port *
658-
mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_port *port,
659-
struct mlxsw_sp_span_entry *span_entry)
660-
{
661-
struct mlxsw_sp_span_inspected_port *p;
662-
663-
list_for_each_entry(p, &span_entry->bound_ports_list, list)
664-
if (port->local_port == p->local_port)
665-
return p;
666-
return NULL;
667-
}
668-
669-
static int
670-
mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port,
671-
struct mlxsw_sp_span_entry *span_entry,
672-
enum mlxsw_sp_span_type type,
673-
bool bind)
674-
{
675-
struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
676-
char mpar_pl[MLXSW_REG_MPAR_LEN];
677-
int pa_id = span_entry->id;
678-
679-
/* bind the port to the SPAN entry */
680-
mlxsw_reg_mpar_pack(mpar_pl, port->local_port,
681-
(enum mlxsw_reg_mpar_i_e) type, bind, pa_id);
682-
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpar), mpar_pl);
683-
}
684-
685-
static int
686-
mlxsw_sp_span_inspected_port_add(struct mlxsw_sp_port *port,
687-
struct mlxsw_sp_span_entry *span_entry,
688-
enum mlxsw_sp_span_type type,
689-
bool bind)
690-
{
691-
struct mlxsw_sp_span_inspected_port *inspected_port;
692-
struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
693-
char sbib_pl[MLXSW_REG_SBIB_LEN];
694-
int err;
695-
696-
/* if it is an egress SPAN, bind a shared buffer to it */
697-
if (type == MLXSW_SP_SPAN_EGRESS) {
698-
u32 buffsize = mlxsw_sp_span_mtu_to_buffsize(mlxsw_sp,
699-
port->dev->mtu);
700-
701-
mlxsw_reg_sbib_pack(sbib_pl, port->local_port, buffsize);
702-
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
703-
if (err) {
704-
netdev_err(port->dev, "Could not create shared buffer for mirroring\n");
705-
return err;
706-
}
707-
}
708-
709-
if (bind) {
710-
err = mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
711-
true);
712-
if (err)
713-
goto err_port_bind;
714-
}
715-
716-
inspected_port = kzalloc(sizeof(*inspected_port), GFP_KERNEL);
717-
if (!inspected_port) {
718-
err = -ENOMEM;
719-
goto err_inspected_port_alloc;
720-
}
721-
inspected_port->local_port = port->local_port;
722-
inspected_port->type = type;
723-
list_add_tail(&inspected_port->list, &span_entry->bound_ports_list);
724-
725-
return 0;
726-
727-
err_inspected_port_alloc:
728-
if (bind)
729-
mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
730-
false);
731-
err_port_bind:
732-
if (type == MLXSW_SP_SPAN_EGRESS) {
733-
mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0);
734-
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
735-
}
736-
return err;
737-
}
738-
739-
static void
740-
mlxsw_sp_span_inspected_port_del(struct mlxsw_sp_port *port,
741-
struct mlxsw_sp_span_entry *span_entry,
742-
enum mlxsw_sp_span_type type,
743-
bool bind)
744-
{
745-
struct mlxsw_sp_span_inspected_port *inspected_port;
746-
struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
747-
char sbib_pl[MLXSW_REG_SBIB_LEN];
748-
749-
inspected_port = mlxsw_sp_span_entry_bound_port_find(port, span_entry);
750-
if (!inspected_port)
751-
return;
752-
753-
if (bind)
754-
mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
755-
false);
756-
/* remove the SBIB buffer if it was egress SPAN */
757-
if (type == MLXSW_SP_SPAN_EGRESS) {
758-
mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0);
759-
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
760-
}
761-
762-
mlxsw_sp_span_entry_put(mlxsw_sp, span_entry);
763-
764-
list_del(&inspected_port->list);
765-
kfree(inspected_port);
766-
}
767-
768-
int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
769-
struct mlxsw_sp_port *to,
770-
enum mlxsw_sp_span_type type, bool bind)
771-
{
772-
struct mlxsw_sp *mlxsw_sp = from->mlxsw_sp;
773-
struct mlxsw_sp_span_entry *span_entry;
774-
int err;
775-
776-
span_entry = mlxsw_sp_span_entry_get(to);
777-
if (!span_entry)
778-
return -ENOENT;
779-
780-
netdev_dbg(from->dev, "Adding inspected port to SPAN entry %d\n",
781-
span_entry->id);
782-
783-
err = mlxsw_sp_span_inspected_port_add(from, span_entry, type, bind);
784-
if (err)
785-
goto err_port_bind;
786-
787-
return 0;
788-
789-
err_port_bind:
790-
mlxsw_sp_span_entry_put(mlxsw_sp, span_entry);
791-
return err;
792-
}
793-
794-
void mlxsw_sp_span_mirror_del(struct mlxsw_sp_port *from, u8 destination_port,
795-
enum mlxsw_sp_span_type type, bool bind)
796-
{
797-
struct mlxsw_sp_span_entry *span_entry;
798-
799-
span_entry = mlxsw_sp_span_entry_find(from->mlxsw_sp,
800-
destination_port);
801-
if (!span_entry) {
802-
netdev_err(from->dev, "no span entry found\n");
803-
return;
804-
}
805-
806-
netdev_dbg(from->dev, "removing inspected port from SPAN entry %d\n",
807-
span_entry->id);
808-
mlxsw_sp_span_inspected_port_del(from, span_entry, type, bind);
809-
}
810-
811491
static int mlxsw_sp_port_sample_set(struct mlxsw_sp_port *mlxsw_sp_port,
812492
bool enable, u32 rate)
813493
{

drivers/net/ethernet/mellanox/mlxsw/spectrum.h

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ enum mlxsw_sp_resource_id {
8080

8181
struct mlxsw_sp_port;
8282
struct mlxsw_sp_rif;
83+
struct mlxsw_sp_span_entry;
8384

8485
struct mlxsw_sp_upper {
8586
struct net_device *dev;
@@ -111,25 +112,6 @@ struct mlxsw_sp_mid {
111112
unsigned long *ports_in_mid; /* bits array */
112113
};
113114

114-
enum mlxsw_sp_span_type {
115-
MLXSW_SP_SPAN_EGRESS,
116-
MLXSW_SP_SPAN_INGRESS
117-
};
118-
119-
struct mlxsw_sp_span_inspected_port {
120-
struct list_head list;
121-
enum mlxsw_sp_span_type type;
122-
u8 local_port;
123-
};
124-
125-
struct mlxsw_sp_span_entry {
126-
u8 local_port;
127-
bool used;
128-
struct list_head bound_ports_list;
129-
int ref_count;
130-
int id;
131-
};
132-
133115
enum mlxsw_sp_port_mall_action_type {
134116
MLXSW_SP_PORT_MALL_MIRROR,
135117
MLXSW_SP_PORT_MALL_SAMPLE,
@@ -396,16 +378,6 @@ struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev);
396378
struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev);
397379
void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port);
398380
struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu(struct net_device *dev);
399-
int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
400-
struct mlxsw_sp_port *to,
401-
enum mlxsw_sp_span_type type,
402-
bool bind);
403-
void mlxsw_sp_span_mirror_del(struct mlxsw_sp_port *from,
404-
u8 destination_port,
405-
enum mlxsw_sp_span_type type,
406-
bool bind);
407-
struct mlxsw_sp_span_entry *
408-
mlxsw_sp_span_entry_find(struct mlxsw_sp *mlxsw_sp, u8 local_port);
409381

410382
/* spectrum_dcb.c */
411383
#ifdef CONFIG_MLXSW_SPECTRUM_DCB

0 commit comments

Comments
 (0)