aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4.h131
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c294
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/l2t.c32
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/l2t.h3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.c22
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_msg.h1
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h279
8 files changed, 757 insertions, 7 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 378988b5709a..24ce797ddbbd 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -545,6 +545,129 @@ struct adapter {
545 spinlock_t stats_lock; 545 spinlock_t stats_lock;
546}; 546};
547 547
548/* Defined bit width of user definable filter tuples
549 */
550#define ETHTYPE_BITWIDTH 16
551#define FRAG_BITWIDTH 1
552#define MACIDX_BITWIDTH 9
553#define FCOE_BITWIDTH 1
554#define IPORT_BITWIDTH 3
555#define MATCHTYPE_BITWIDTH 3
556#define PROTO_BITWIDTH 8
557#define TOS_BITWIDTH 8
558#define PF_BITWIDTH 8
559#define VF_BITWIDTH 8
560#define IVLAN_BITWIDTH 16
561#define OVLAN_BITWIDTH 16
562
563/* Filter matching rules. These consist of a set of ingress packet field
564 * (value, mask) tuples. The associated ingress packet field matches the
565 * tuple when ((field & mask) == value). (Thus a wildcard "don't care" field
566 * rule can be constructed by specifying a tuple of (0, 0).) A filter rule
567 * matches an ingress packet when all of the individual individual field
568 * matching rules are true.
569 *
570 * Partial field masks are always valid, however, while it may be easy to
571 * understand their meanings for some fields (e.g. IP address to match a
572 * subnet), for others making sensible partial masks is less intuitive (e.g.
573 * MPS match type) ...
574 *
575 * Most of the following data structures are modeled on T4 capabilities.
576 * Drivers for earlier chips use the subsets which make sense for those chips.
577 * We really need to come up with a hardware-independent mechanism to
578 * represent hardware filter capabilities ...
579 */
580struct ch_filter_tuple {
581 /* Compressed header matching field rules. The TP_VLAN_PRI_MAP
582 * register selects which of these fields will participate in the
583 * filter match rules -- up to a maximum of 36 bits. Because
584 * TP_VLAN_PRI_MAP is a global register, all filters must use the same
585 * set of fields.
586 */
587 uint32_t ethtype:ETHTYPE_BITWIDTH; /* Ethernet type */
588 uint32_t frag:FRAG_BITWIDTH; /* IP fragmentation header */
589 uint32_t ivlan_vld:1; /* inner VLAN valid */
590 uint32_t ovlan_vld:1; /* outer VLAN valid */
591 uint32_t pfvf_vld:1; /* PF/VF valid */
592 uint32_t macidx:MACIDX_BITWIDTH; /* exact match MAC index */
593 uint32_t fcoe:FCOE_BITWIDTH; /* FCoE packet */
594 uint32_t iport:IPORT_BITWIDTH; /* ingress port */
595 uint32_t matchtype:MATCHTYPE_BITWIDTH; /* MPS match type */
596 uint32_t proto:PROTO_BITWIDTH; /* protocol type */
597 uint32_t tos:TOS_BITWIDTH; /* TOS/Traffic Type */
598 uint32_t pf:PF_BITWIDTH; /* PCI-E PF ID */
599 uint32_t vf:VF_BITWIDTH; /* PCI-E VF ID */
600 uint32_t ivlan:IVLAN_BITWIDTH; /* inner VLAN */
601 uint32_t ovlan:OVLAN_BITWIDTH; /* outer VLAN */
602
603 /* Uncompressed header matching field rules. These are always
604 * available for field rules.
605 */
606 uint8_t lip[16]; /* local IP address (IPv4 in [3:0]) */
607 uint8_t fip[16]; /* foreign IP address (IPv4 in [3:0]) */
608 uint16_t lport; /* local port */
609 uint16_t fport; /* foreign port */
610};
611
612/* A filter ioctl command.
613 */
614struct ch_filter_specification {
615 /* Administrative fields for filter.
616 */
617 uint32_t hitcnts:1; /* count filter hits in TCB */
618 uint32_t prio:1; /* filter has priority over active/server */
619
620 /* Fundamental filter typing. This is the one element of filter
621 * matching that doesn't exist as a (value, mask) tuple.
622 */
623 uint32_t type:1; /* 0 => IPv4, 1 => IPv6 */
624
625 /* Packet dispatch information. Ingress packets which match the
626 * filter rules will be dropped, passed to the host or switched back
627 * out as egress packets.
628 */
629 uint32_t action:2; /* drop, pass, switch */
630
631 uint32_t rpttid:1; /* report TID in RSS hash field */
632
633 uint32_t dirsteer:1; /* 0 => RSS, 1 => steer to iq */
634 uint32_t iq:10; /* ingress queue */
635
636 uint32_t maskhash:1; /* dirsteer=0: store RSS hash in TCB */
637 uint32_t dirsteerhash:1;/* dirsteer=1: 0 => TCB contains RSS hash */
638 /* 1 => TCB contains IQ ID */
639
640 /* Switch proxy/rewrite fields. An ingress packet which matches a
641 * filter with "switch" set will be looped back out as an egress
642 * packet -- potentially with some Ethernet header rewriting.
643 */
644 uint32_t eport:2; /* egress port to switch packet out */
645 uint32_t newdmac:1; /* rewrite destination MAC address */
646 uint32_t newsmac:1; /* rewrite source MAC address */
647 uint32_t newvlan:2; /* rewrite VLAN Tag */
648 uint8_t dmac[ETH_ALEN]; /* new destination MAC address */
649 uint8_t smac[ETH_ALEN]; /* new source MAC address */
650 uint16_t vlan; /* VLAN Tag to insert */
651
652 /* Filter rule value/mask pairs.
653 */
654 struct ch_filter_tuple val;
655 struct ch_filter_tuple mask;
656};
657
658enum {
659 FILTER_PASS = 0, /* default */
660 FILTER_DROP,
661 FILTER_SWITCH
662};
663
664enum {
665 VLAN_NOCHANGE = 0, /* default */
666 VLAN_REMOVE,
667 VLAN_INSERT,
668 VLAN_REWRITE
669};
670
548static inline u32 t4_read_reg(struct adapter *adap, u32 reg_addr) 671static inline u32 t4_read_reg(struct adapter *adap, u32 reg_addr)
549{ 672{
550 return readl(adap->regs + reg_addr); 673 return readl(adap->regs + reg_addr);
@@ -701,6 +824,12 @@ static inline int t4_wr_mbox_ns(struct adapter *adap, int mbox, const void *cmd,
701void t4_write_indirect(struct adapter *adap, unsigned int addr_reg, 824void t4_write_indirect(struct adapter *adap, unsigned int addr_reg,
702 unsigned int data_reg, const u32 *vals, 825 unsigned int data_reg, const u32 *vals,
703 unsigned int nregs, unsigned int start_idx); 826 unsigned int nregs, unsigned int start_idx);
827void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
828 unsigned int data_reg, u32 *vals, unsigned int nregs,
829 unsigned int start_idx);
830
831struct fw_filter_wr;
832
704void t4_intr_enable(struct adapter *adapter); 833void t4_intr_enable(struct adapter *adapter);
705void t4_intr_disable(struct adapter *adapter); 834void t4_intr_disable(struct adapter *adapter);
706int t4_slow_intr_handler(struct adapter *adapter); 835int t4_slow_intr_handler(struct adapter *adapter);
@@ -737,6 +866,8 @@ void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4,
737void t4_load_mtus(struct adapter *adap, const unsigned short *mtus, 866void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
738 const unsigned short *alpha, const unsigned short *beta); 867 const unsigned short *alpha, const unsigned short *beta);
739 868
869void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid);
870
740void t4_wol_magic_enable(struct adapter *adap, unsigned int port, 871void t4_wol_magic_enable(struct adapter *adap, unsigned int port,
741 const u8 *addr); 872 const u8 *addr);
742int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map, 873int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index a27b4ae20f43..41537a403eef 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -175,6 +175,30 @@ enum {
175 MIN_FL_ENTRIES = 16 175 MIN_FL_ENTRIES = 16
176}; 176};
177 177
178/* Host shadow copy of ingress filter entry. This is in host native format
179 * and doesn't match the ordering or bit order, etc. of the hardware of the
180 * firmware command. The use of bit-field structure elements is purely to
181 * remind ourselves of the field size limitations and save memory in the case
182 * where the filter table is large.
183 */
184struct filter_entry {
185 /* Administrative fields for filter.
186 */
187 u32 valid:1; /* filter allocated and valid */
188 u32 locked:1; /* filter is administratively locked */
189
190 u32 pending:1; /* filter action is pending firmware reply */
191 u32 smtidx:8; /* Source MAC Table index for smac */
192 struct l2t_entry *l2t; /* Layer Two Table entry for dmac */
193
194 /* The filter itself. Most of this is a straight copy of information
195 * provided by the extended ioctl(). Some fields are translated to
196 * internal forms -- for instance the Ingress Queue ID passed in from
197 * the ioctl() is translated into the Absolute Ingress Queue ID.
198 */
199 struct ch_filter_specification fs;
200};
201
178#define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \ 202#define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \
179 NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\ 203 NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\
180 NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) 204 NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
@@ -325,6 +349,9 @@ enum {
325 349
326static unsigned int tp_vlan_pri_map = TP_VLAN_PRI_MAP_DEFAULT; 350static unsigned int tp_vlan_pri_map = TP_VLAN_PRI_MAP_DEFAULT;
327 351
352module_param(tp_vlan_pri_map, uint, 0644);
353MODULE_PARM_DESC(tp_vlan_pri_map, "global compressed filter configuration");
354
328static struct dentry *cxgb4_debugfs_root; 355static struct dentry *cxgb4_debugfs_root;
329 356
330static LIST_HEAD(adapter_list); 357static LIST_HEAD(adapter_list);
@@ -506,8 +533,67 @@ static int link_start(struct net_device *dev)
506 return ret; 533 return ret;
507} 534}
508 535
509/* 536/* Clear a filter and release any of its resources that we own. This also
510 * Response queue handler for the FW event queue. 537 * clears the filter's "pending" status.
538 */
539static void clear_filter(struct adapter *adap, struct filter_entry *f)
540{
541 /* If the new or old filter have loopback rewriteing rules then we'll
542 * need to free any existing Layer Two Table (L2T) entries of the old
543 * filter rule. The firmware will handle freeing up any Source MAC
544 * Table (SMT) entries used for rewriting Source MAC Addresses in
545 * loopback rules.
546 */
547 if (f->l2t)
548 cxgb4_l2t_release(f->l2t);
549
550 /* The zeroing of the filter rule below clears the filter valid,
551 * pending, locked flags, l2t pointer, etc. so it's all we need for
552 * this operation.
553 */
554 memset(f, 0, sizeof(*f));
555}
556
557/* Handle a filter write/deletion reply.
558 */
559static void filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl)
560{
561 unsigned int idx = GET_TID(rpl);
562 unsigned int nidx = idx - adap->tids.ftid_base;
563 unsigned int ret;
564 struct filter_entry *f;
565
566 if (idx >= adap->tids.ftid_base && nidx <
567 (adap->tids.nftids + adap->tids.nsftids)) {
568 idx = nidx;
569 ret = GET_TCB_COOKIE(rpl->cookie);
570 f = &adap->tids.ftid_tab[idx];
571
572 if (ret == FW_FILTER_WR_FLT_DELETED) {
573 /* Clear the filter when we get confirmation from the
574 * hardware that the filter has been deleted.
575 */
576 clear_filter(adap, f);
577 } else if (ret == FW_FILTER_WR_SMT_TBL_FULL) {
578 dev_err(adap->pdev_dev, "filter %u setup failed due to full SMT\n",
579 idx);
580 clear_filter(adap, f);
581 } else if (ret == FW_FILTER_WR_FLT_ADDED) {
582 f->smtidx = (be64_to_cpu(rpl->oldval) >> 24) & 0xff;
583 f->pending = 0; /* asynchronous setup completed */
584 f->valid = 1;
585 } else {
586 /* Something went wrong. Issue a warning about the
587 * problem and clear everything out.
588 */
589 dev_err(adap->pdev_dev, "filter %u setup failed with error %u\n",
590 idx, ret);
591 clear_filter(adap, f);
592 }
593 }
594}
595
596/* Response queue handler for the FW event queue.
511 */ 597 */
512static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp, 598static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
513 const struct pkt_gl *gl) 599 const struct pkt_gl *gl)
@@ -542,6 +628,10 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
542 const struct cpl_l2t_write_rpl *p = (void *)rsp; 628 const struct cpl_l2t_write_rpl *p = (void *)rsp;
543 629
544 do_l2t_write_rpl(q->adap, p); 630 do_l2t_write_rpl(q->adap, p);
631 } else if (opcode == CPL_SET_TCB_RPL) {
632 const struct cpl_set_tcb_rpl *p = (void *)rsp;
633
634 filter_rpl(q->adap, p);
545 } else 635 } else
546 dev_err(q->adap->pdev_dev, 636 dev_err(q->adap->pdev_dev,
547 "unexpected CPL %#x on FW event queue\n", opcode); 637 "unexpected CPL %#x on FW event queue\n", opcode);
@@ -983,6 +1073,148 @@ static void t4_free_mem(void *addr)
983 kfree(addr); 1073 kfree(addr);
984} 1074}
985 1075
1076/* Send a Work Request to write the filter at a specified index. We construct
1077 * a Firmware Filter Work Request to have the work done and put the indicated
1078 * filter into "pending" mode which will prevent any further actions against
1079 * it till we get a reply from the firmware on the completion status of the
1080 * request.
1081 */
1082static int set_filter_wr(struct adapter *adapter, int fidx)
1083{
1084 struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
1085 struct sk_buff *skb;
1086 struct fw_filter_wr *fwr;
1087 unsigned int ftid;
1088
1089 /* If the new filter requires loopback Destination MAC and/or VLAN
1090 * rewriting then we need to allocate a Layer 2 Table (L2T) entry for
1091 * the filter.
1092 */
1093 if (f->fs.newdmac || f->fs.newvlan) {
1094 /* allocate L2T entry for new filter */
1095 f->l2t = t4_l2t_alloc_switching(adapter->l2t);
1096 if (f->l2t == NULL)
1097 return -EAGAIN;
1098 if (t4_l2t_set_switching(adapter, f->l2t, f->fs.vlan,
1099 f->fs.eport, f->fs.dmac)) {
1100 cxgb4_l2t_release(f->l2t);
1101 f->l2t = NULL;
1102 return -ENOMEM;
1103 }
1104 }
1105
1106 ftid = adapter->tids.ftid_base + fidx;
1107
1108 skb = alloc_skb(sizeof(*fwr), GFP_KERNEL | __GFP_NOFAIL);
1109 fwr = (struct fw_filter_wr *)__skb_put(skb, sizeof(*fwr));
1110 memset(fwr, 0, sizeof(*fwr));
1111
1112 /* It would be nice to put most of the following in t4_hw.c but most
1113 * of the work is translating the cxgbtool ch_filter_specification
1114 * into the Work Request and the definition of that structure is
1115 * currently in cxgbtool.h which isn't appropriate to pull into the
1116 * common code. We may eventually try to come up with a more neutral
1117 * filter specification structure but for now it's easiest to simply
1118 * put this fairly direct code in line ...
1119 */
1120 fwr->op_pkd = htonl(FW_WR_OP(FW_FILTER_WR));
1121 fwr->len16_pkd = htonl(FW_WR_LEN16(sizeof(*fwr)/16));
1122 fwr->tid_to_iq =
1123 htonl(V_FW_FILTER_WR_TID(ftid) |
1124 V_FW_FILTER_WR_RQTYPE(f->fs.type) |
1125 V_FW_FILTER_WR_NOREPLY(0) |
1126 V_FW_FILTER_WR_IQ(f->fs.iq));
1127 fwr->del_filter_to_l2tix =
1128 htonl(V_FW_FILTER_WR_RPTTID(f->fs.rpttid) |
1129 V_FW_FILTER_WR_DROP(f->fs.action == FILTER_DROP) |
1130 V_FW_FILTER_WR_DIRSTEER(f->fs.dirsteer) |
1131 V_FW_FILTER_WR_MASKHASH(f->fs.maskhash) |
1132 V_FW_FILTER_WR_DIRSTEERHASH(f->fs.dirsteerhash) |
1133 V_FW_FILTER_WR_LPBK(f->fs.action == FILTER_SWITCH) |
1134 V_FW_FILTER_WR_DMAC(f->fs.newdmac) |
1135 V_FW_FILTER_WR_SMAC(f->fs.newsmac) |
1136 V_FW_FILTER_WR_INSVLAN(f->fs.newvlan == VLAN_INSERT ||
1137 f->fs.newvlan == VLAN_REWRITE) |
1138 V_FW_FILTER_WR_RMVLAN(f->fs.newvlan == VLAN_REMOVE ||
1139 f->fs.newvlan == VLAN_REWRITE) |
1140 V_FW_FILTER_WR_HITCNTS(f->fs.hitcnts) |
1141 V_FW_FILTER_WR_TXCHAN(f->fs.eport) |
1142 V_FW_FILTER_WR_PRIO(f->fs.prio) |
1143 V_FW_FILTER_WR_L2TIX(f->l2t ? f->l2t->idx : 0));
1144 fwr->ethtype = htons(f->fs.val.ethtype);
1145 fwr->ethtypem = htons(f->fs.mask.ethtype);
1146 fwr->frag_to_ovlan_vldm =
1147 (V_FW_FILTER_WR_FRAG(f->fs.val.frag) |
1148 V_FW_FILTER_WR_FRAGM(f->fs.mask.frag) |
1149 V_FW_FILTER_WR_IVLAN_VLD(f->fs.val.ivlan_vld) |
1150 V_FW_FILTER_WR_OVLAN_VLD(f->fs.val.ovlan_vld) |
1151 V_FW_FILTER_WR_IVLAN_VLDM(f->fs.mask.ivlan_vld) |
1152 V_FW_FILTER_WR_OVLAN_VLDM(f->fs.mask.ovlan_vld));
1153 fwr->smac_sel = 0;
1154 fwr->rx_chan_rx_rpl_iq =
1155 htons(V_FW_FILTER_WR_RX_CHAN(0) |
1156 V_FW_FILTER_WR_RX_RPL_IQ(adapter->sge.fw_evtq.abs_id));
1157 fwr->maci_to_matchtypem =
1158 htonl(V_FW_FILTER_WR_MACI(f->fs.val.macidx) |
1159 V_FW_FILTER_WR_MACIM(f->fs.mask.macidx) |
1160 V_FW_FILTER_WR_FCOE(f->fs.val.fcoe) |
1161 V_FW_FILTER_WR_FCOEM(f->fs.mask.fcoe) |
1162 V_FW_FILTER_WR_PORT(f->fs.val.iport) |
1163 V_FW_FILTER_WR_PORTM(f->fs.mask.iport) |
1164 V_FW_FILTER_WR_MATCHTYPE(f->fs.val.matchtype) |
1165 V_FW_FILTER_WR_MATCHTYPEM(f->fs.mask.matchtype));
1166 fwr->ptcl = f->fs.val.proto;
1167 fwr->ptclm = f->fs.mask.proto;
1168 fwr->ttyp = f->fs.val.tos;
1169 fwr->ttypm = f->fs.mask.tos;
1170 fwr->ivlan = htons(f->fs.val.ivlan);
1171 fwr->ivlanm = htons(f->fs.mask.ivlan);
1172 fwr->ovlan = htons(f->fs.val.ovlan);
1173 fwr->ovlanm = htons(f->fs.mask.ovlan);
1174 memcpy(fwr->lip, f->fs.val.lip, sizeof(fwr->lip));
1175 memcpy(fwr->lipm, f->fs.mask.lip, sizeof(fwr->lipm));
1176 memcpy(fwr->fip, f->fs.val.fip, sizeof(fwr->fip));
1177 memcpy(fwr->fipm, f->fs.mask.fip, sizeof(fwr->fipm));
1178 fwr->lp = htons(f->fs.val.lport);
1179 fwr->lpm = htons(f->fs.mask.lport);
1180 fwr->fp = htons(f->fs.val.fport);
1181 fwr->fpm = htons(f->fs.mask.fport);
1182 if (f->fs.newsmac)
1183 memcpy(fwr->sma, f->fs.smac, sizeof(fwr->sma));
1184
1185 /* Mark the filter as "pending" and ship off the Filter Work Request.
1186 * When we get the Work Request Reply we'll clear the pending status.
1187 */
1188 f->pending = 1;
1189 set_wr_txq(skb, CPL_PRIORITY_CONTROL, f->fs.val.iport & 0x3);
1190 t4_ofld_send(adapter, skb);
1191 return 0;
1192}
1193
1194/* Delete the filter at a specified index.
1195 */
1196static int del_filter_wr(struct adapter *adapter, int fidx)
1197{
1198 struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
1199 struct sk_buff *skb;
1200 struct fw_filter_wr *fwr;
1201 unsigned int len, ftid;
1202
1203 len = sizeof(*fwr);
1204 ftid = adapter->tids.ftid_base + fidx;
1205
1206 skb = alloc_skb(len, GFP_KERNEL | __GFP_NOFAIL);
1207 fwr = (struct fw_filter_wr *)__skb_put(skb, len);
1208 t4_mk_filtdelwr(ftid, fwr, adapter->sge.fw_evtq.abs_id);
1209
1210 /* Mark the filter as "pending" and ship off the Filter Work Request.
1211 * When we get the Work Request Reply we'll clear the pending status.
1212 */
1213 f->pending = 1;
1214 t4_mgmt_tx(adapter, skb);
1215 return 0;
1216}
1217
986static inline int is_offload(const struct adapter *adap) 1218static inline int is_offload(const struct adapter *adap)
987{ 1219{
988 return adap->params.offload; 1220 return adap->params.offload;
@@ -2195,7 +2427,7 @@ int cxgb4_alloc_atid(struct tid_info *t, void *data)
2195 if (t->afree) { 2427 if (t->afree) {
2196 union aopen_entry *p = t->afree; 2428 union aopen_entry *p = t->afree;
2197 2429
2198 atid = p - t->atid_tab; 2430 atid = (p - t->atid_tab) + t->atid_base;
2199 t->afree = p->next; 2431 t->afree = p->next;
2200 p->data = data; 2432 p->data = data;
2201 t->atids_in_use++; 2433 t->atids_in_use++;
@@ -2210,7 +2442,7 @@ EXPORT_SYMBOL(cxgb4_alloc_atid);
2210 */ 2442 */
2211void cxgb4_free_atid(struct tid_info *t, unsigned int atid) 2443void cxgb4_free_atid(struct tid_info *t, unsigned int atid)
2212{ 2444{
2213 union aopen_entry *p = &t->atid_tab[atid]; 2445 union aopen_entry *p = &t->atid_tab[atid - t->atid_base];
2214 2446
2215 spin_lock_bh(&t->atid_lock); 2447 spin_lock_bh(&t->atid_lock);
2216 p->next = t->afree; 2448 p->next = t->afree;
@@ -2362,11 +2594,16 @@ EXPORT_SYMBOL(cxgb4_remove_tid);
2362static int tid_init(struct tid_info *t) 2594static int tid_init(struct tid_info *t)
2363{ 2595{
2364 size_t size; 2596 size_t size;
2597 unsigned int stid_bmap_size;
2365 unsigned int natids = t->natids; 2598 unsigned int natids = t->natids;
2366 2599
2367 size = t->ntids * sizeof(*t->tid_tab) + natids * sizeof(*t->atid_tab) + 2600 stid_bmap_size = BITS_TO_LONGS(t->nstids);
2601 size = t->ntids * sizeof(*t->tid_tab) +
2602 natids * sizeof(*t->atid_tab) +
2368 t->nstids * sizeof(*t->stid_tab) + 2603 t->nstids * sizeof(*t->stid_tab) +
2369 BITS_TO_LONGS(t->nstids) * sizeof(long); 2604 stid_bmap_size * sizeof(long) +
2605 t->nftids * sizeof(*t->ftid_tab);
2606
2370 t->tid_tab = t4_alloc_mem(size); 2607 t->tid_tab = t4_alloc_mem(size);
2371 if (!t->tid_tab) 2608 if (!t->tid_tab)
2372 return -ENOMEM; 2609 return -ENOMEM;
@@ -2374,6 +2611,7 @@ static int tid_init(struct tid_info *t)
2374 t->atid_tab = (union aopen_entry *)&t->tid_tab[t->ntids]; 2611 t->atid_tab = (union aopen_entry *)&t->tid_tab[t->ntids];
2375 t->stid_tab = (struct serv_entry *)&t->atid_tab[natids]; 2612 t->stid_tab = (struct serv_entry *)&t->atid_tab[natids];
2376 t->stid_bmap = (unsigned long *)&t->stid_tab[t->nstids]; 2613 t->stid_bmap = (unsigned long *)&t->stid_tab[t->nstids];
2614 t->ftid_tab = (struct filter_entry *)&t->stid_bmap[stid_bmap_size];
2377 spin_lock_init(&t->stid_lock); 2615 spin_lock_init(&t->stid_lock);
2378 spin_lock_init(&t->atid_lock); 2616 spin_lock_init(&t->atid_lock);
2379 2617
@@ -2999,6 +3237,40 @@ static int cxgb_close(struct net_device *dev)
2999 return t4_enable_vi(adapter, adapter->fn, pi->viid, false, false); 3237 return t4_enable_vi(adapter, adapter->fn, pi->viid, false, false);
3000} 3238}
3001 3239
3240/* Return an error number if the indicated filter isn't writable ...
3241 */
3242static int writable_filter(struct filter_entry *f)
3243{
3244 if (f->locked)
3245 return -EPERM;
3246 if (f->pending)
3247 return -EBUSY;
3248
3249 return 0;
3250}
3251
3252/* Delete the filter at the specified index (if valid). The checks for all
3253 * the common problems with doing this like the filter being locked, currently
3254 * pending in another operation, etc.
3255 */
3256static int delete_filter(struct adapter *adapter, unsigned int fidx)
3257{
3258 struct filter_entry *f;
3259 int ret;
3260
3261 if (fidx >= adapter->tids.nftids)
3262 return -EINVAL;
3263
3264 f = &adapter->tids.ftid_tab[fidx];
3265 ret = writable_filter(f);
3266 if (ret)
3267 return ret;
3268 if (f->valid)
3269 return del_filter_wr(adapter, fidx);
3270
3271 return 0;
3272}
3273
3002static struct rtnl_link_stats64 *cxgb_get_stats(struct net_device *dev, 3274static struct rtnl_link_stats64 *cxgb_get_stats(struct net_device *dev,
3003 struct rtnl_link_stats64 *ns) 3275 struct rtnl_link_stats64 *ns)
3004{ 3276{
@@ -4661,6 +4933,16 @@ static void remove_one(struct pci_dev *pdev)
4661 if (adapter->debugfs_root) 4933 if (adapter->debugfs_root)
4662 debugfs_remove_recursive(adapter->debugfs_root); 4934 debugfs_remove_recursive(adapter->debugfs_root);
4663 4935
4936 /* If we allocated filters, free up state associated with any
4937 * valid filters ...
4938 */
4939 if (adapter->tids.ftid_tab) {
4940 struct filter_entry *f = &adapter->tids.ftid_tab[0];
4941 for (i = 0; i < adapter->tids.nftids; i++, f++)
4942 if (f->valid)
4943 clear_filter(adapter, f);
4944 }
4945
4664 if (adapter->flags & FULL_INIT_DONE) 4946 if (adapter->flags & FULL_INIT_DONE)
4665 cxgb_down(adapter); 4947 cxgb_down(adapter);
4666 4948
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
index 39bec73ff87c..59a61332b78c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
@@ -97,7 +97,9 @@ struct tid_info {
97 97
98 union aopen_entry *atid_tab; 98 union aopen_entry *atid_tab;
99 unsigned int natids; 99 unsigned int natids;
100 unsigned int atid_base;
100 101
102 struct filter_entry *ftid_tab;
101 unsigned int nftids; 103 unsigned int nftids;
102 unsigned int ftid_base; 104 unsigned int ftid_base;
103 unsigned int aftid_base; 105 unsigned int aftid_base;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/l2t.c b/drivers/net/ethernet/chelsio/cxgb4/l2t.c
index 6ac77a62f361..29878098101e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/l2t.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/l2t.c
@@ -484,6 +484,38 @@ void t4_l2t_update(struct adapter *adap, struct neighbour *neigh)
484 handle_failed_resolution(adap, arpq); 484 handle_failed_resolution(adap, arpq);
485} 485}
486 486
487/* Allocate an L2T entry for use by a switching rule. Such need to be
488 * explicitly freed and while busy they are not on any hash chain, so normal
489 * address resolution updates do not see them.
490 */
491struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d)
492{
493 struct l2t_entry *e;
494
495 write_lock_bh(&d->lock);
496 e = alloc_l2e(d);
497 if (e) {
498 spin_lock(&e->lock); /* avoid race with t4_l2t_free */
499 e->state = L2T_STATE_SWITCHING;
500 atomic_set(&e->refcnt, 1);
501 spin_unlock(&e->lock);
502 }
503 write_unlock_bh(&d->lock);
504 return e;
505}
506
507/* Sets/updates the contents of a switching L2T entry that has been allocated
508 * with an earlier call to @t4_l2t_alloc_switching.
509 */
510int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan,
511 u8 port, u8 *eth_addr)
512{
513 e->vlan = vlan;
514 e->lport = port;
515 memcpy(e->dmac, eth_addr, ETH_ALEN);
516 return write_l2e(adap, e, 0);
517}
518
487struct l2t_data *t4_init_l2t(void) 519struct l2t_data *t4_init_l2t(void)
488{ 520{
489 int i; 521 int i;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/l2t.h b/drivers/net/ethernet/chelsio/cxgb4/l2t.h
index 02b31d0c6410..108c0f1fce1c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/l2t.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/l2t.h
@@ -100,6 +100,9 @@ struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh,
100 unsigned int priority); 100 unsigned int priority);
101 101
102void t4_l2t_update(struct adapter *adap, struct neighbour *neigh); 102void t4_l2t_update(struct adapter *adap, struct neighbour *neigh);
103struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d);
104int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan,
105 u8 port, u8 *eth_addr);
103struct l2t_data *t4_init_l2t(void); 106struct l2t_data *t4_init_l2t(void);
104void do_l2t_write_rpl(struct adapter *p, const struct cpl_l2t_write_rpl *rpl); 107void do_l2t_write_rpl(struct adapter *p, const struct cpl_l2t_write_rpl *rpl);
105 108
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 8d9c7547b070..22f3af5166bf 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -109,7 +109,7 @@ void t4_set_reg_field(struct adapter *adapter, unsigned int addr, u32 mask,
109 * Reads registers that are accessed indirectly through an address/data 109 * Reads registers that are accessed indirectly through an address/data
110 * register pair. 110 * register pair.
111 */ 111 */
112static void t4_read_indirect(struct adapter *adap, unsigned int addr_reg, 112void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
113 unsigned int data_reg, u32 *vals, 113 unsigned int data_reg, u32 *vals,
114 unsigned int nregs, unsigned int start_idx) 114 unsigned int nregs, unsigned int start_idx)
115{ 115{
@@ -2268,6 +2268,26 @@ int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
2268 return 0; 2268 return 0;
2269} 2269}
2270 2270
2271/* t4_mk_filtdelwr - create a delete filter WR
2272 * @ftid: the filter ID
2273 * @wr: the filter work request to populate
2274 * @qid: ingress queue to receive the delete notification
2275 *
2276 * Creates a filter work request to delete the supplied filter. If @qid is
2277 * negative the delete notification is suppressed.
2278 */
2279void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid)
2280{
2281 memset(wr, 0, sizeof(*wr));
2282 wr->op_pkd = htonl(FW_WR_OP(FW_FILTER_WR));
2283 wr->len16_pkd = htonl(FW_WR_LEN16(sizeof(*wr) / 16));
2284 wr->tid_to_iq = htonl(V_FW_FILTER_WR_TID(ftid) |
2285 V_FW_FILTER_WR_NOREPLY(qid < 0));
2286 wr->del_filter_to_l2tix = htonl(F_FW_FILTER_WR_DEL_FILTER);
2287 if (qid >= 0)
2288 wr->rx_chan_rx_rpl_iq = htons(V_FW_FILTER_WR_RX_RPL_IQ(qid));
2289}
2290
2271#define INIT_CMD(var, cmd, rd_wr) do { \ 2291#define INIT_CMD(var, cmd, rd_wr) do { \
2272 (var).op_to_write = htonl(FW_CMD_OP(FW_##cmd##_CMD) | \ 2292 (var).op_to_write = htonl(FW_CMD_OP(FW_##cmd##_CMD) | \
2273 FW_CMD_REQUEST | FW_CMD_##rd_wr); \ 2293 FW_CMD_REQUEST | FW_CMD_##rd_wr); \
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
index b760808fd6d9..99ff71764499 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
@@ -332,6 +332,7 @@ struct cpl_set_tcb_field {
332 __be16 word_cookie; 332 __be16 word_cookie;
333#define TCB_WORD(x) ((x) << 0) 333#define TCB_WORD(x) ((x) << 0)
334#define TCB_COOKIE(x) ((x) << 5) 334#define TCB_COOKIE(x) ((x) << 5)
335#define GET_TCB_COOKIE(x) (((x) >> 5) & 7)
335 __be64 mask; 336 __be64 mask;
336 __be64 val; 337 __be64 val;
337}; 338};
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
index 0abc864cdd3a..e98b6fff2c96 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
@@ -35,6 +35,10 @@
35#ifndef _T4FW_INTERFACE_H_ 35#ifndef _T4FW_INTERFACE_H_
36#define _T4FW_INTERFACE_H_ 36#define _T4FW_INTERFACE_H_
37 37
38enum fw_ret_val {
39 FW_ENOEXEC = 8, /* Exec format error; inv microcode */
40};
41
38#define FW_T4VF_SGE_BASE_ADDR 0x0000 42#define FW_T4VF_SGE_BASE_ADDR 0x0000
39#define FW_T4VF_MPS_BASE_ADDR 0x0100 43#define FW_T4VF_MPS_BASE_ADDR 0x0100
40#define FW_T4VF_PL_BASE_ADDR 0x0200 44#define FW_T4VF_PL_BASE_ADDR 0x0200
@@ -82,6 +86,281 @@ struct fw_wr_hdr {
82 86
83#define HW_TPL_FR_MT_PR_IV_P_FC 0X32B 87#define HW_TPL_FR_MT_PR_IV_P_FC 0X32B
84 88
89/* filter wr reply code in cookie in CPL_SET_TCB_RPL */
90enum fw_filter_wr_cookie {
91 FW_FILTER_WR_SUCCESS,
92 FW_FILTER_WR_FLT_ADDED,
93 FW_FILTER_WR_FLT_DELETED,
94 FW_FILTER_WR_SMT_TBL_FULL,
95 FW_FILTER_WR_EINVAL,
96};
97
98struct fw_filter_wr {
99 __be32 op_pkd;
100 __be32 len16_pkd;
101 __be64 r3;
102 __be32 tid_to_iq;
103 __be32 del_filter_to_l2tix;
104 __be16 ethtype;
105 __be16 ethtypem;
106 __u8 frag_to_ovlan_vldm;
107 __u8 smac_sel;
108 __be16 rx_chan_rx_rpl_iq;
109 __be32 maci_to_matchtypem;
110 __u8 ptcl;
111 __u8 ptclm;
112 __u8 ttyp;
113 __u8 ttypm;
114 __be16 ivlan;
115 __be16 ivlanm;
116 __be16 ovlan;
117 __be16 ovlanm;
118 __u8 lip[16];
119 __u8 lipm[16];
120 __u8 fip[16];
121 __u8 fipm[16];
122 __be16 lp;
123 __be16 lpm;
124 __be16 fp;
125 __be16 fpm;
126 __be16 r7;
127 __u8 sma[6];
128};
129
130#define S_FW_FILTER_WR_TID 12
131#define M_FW_FILTER_WR_TID 0xfffff
132#define V_FW_FILTER_WR_TID(x) ((x) << S_FW_FILTER_WR_TID)
133#define G_FW_FILTER_WR_TID(x) \
134 (((x) >> S_FW_FILTER_WR_TID) & M_FW_FILTER_WR_TID)
135
136#define S_FW_FILTER_WR_RQTYPE 11
137#define M_FW_FILTER_WR_RQTYPE 0x1
138#define V_FW_FILTER_WR_RQTYPE(x) ((x) << S_FW_FILTER_WR_RQTYPE)
139#define G_FW_FILTER_WR_RQTYPE(x) \
140 (((x) >> S_FW_FILTER_WR_RQTYPE) & M_FW_FILTER_WR_RQTYPE)
141#define F_FW_FILTER_WR_RQTYPE V_FW_FILTER_WR_RQTYPE(1U)
142
143#define S_FW_FILTER_WR_NOREPLY 10
144#define M_FW_FILTER_WR_NOREPLY 0x1
145#define V_FW_FILTER_WR_NOREPLY(x) ((x) << S_FW_FILTER_WR_NOREPLY)
146#define G_FW_FILTER_WR_NOREPLY(x) \
147 (((x) >> S_FW_FILTER_WR_NOREPLY) & M_FW_FILTER_WR_NOREPLY)
148#define F_FW_FILTER_WR_NOREPLY V_FW_FILTER_WR_NOREPLY(1U)
149
150#define S_FW_FILTER_WR_IQ 0
151#define M_FW_FILTER_WR_IQ 0x3ff
152#define V_FW_FILTER_WR_IQ(x) ((x) << S_FW_FILTER_WR_IQ)
153#define G_FW_FILTER_WR_IQ(x) \
154 (((x) >> S_FW_FILTER_WR_IQ) & M_FW_FILTER_WR_IQ)
155
156#define S_FW_FILTER_WR_DEL_FILTER 31
157#define M_FW_FILTER_WR_DEL_FILTER 0x1
158#define V_FW_FILTER_WR_DEL_FILTER(x) ((x) << S_FW_FILTER_WR_DEL_FILTER)
159#define G_FW_FILTER_WR_DEL_FILTER(x) \
160 (((x) >> S_FW_FILTER_WR_DEL_FILTER) & M_FW_FILTER_WR_DEL_FILTER)
161#define F_FW_FILTER_WR_DEL_FILTER V_FW_FILTER_WR_DEL_FILTER(1U)
162
163#define S_FW_FILTER_WR_RPTTID 25
164#define M_FW_FILTER_WR_RPTTID 0x1
165#define V_FW_FILTER_WR_RPTTID(x) ((x) << S_FW_FILTER_WR_RPTTID)
166#define G_FW_FILTER_WR_RPTTID(x) \
167 (((x) >> S_FW_FILTER_WR_RPTTID) & M_FW_FILTER_WR_RPTTID)
168#define F_FW_FILTER_WR_RPTTID V_FW_FILTER_WR_RPTTID(1U)
169
170#define S_FW_FILTER_WR_DROP 24
171#define M_FW_FILTER_WR_DROP 0x1
172#define V_FW_FILTER_WR_DROP(x) ((x) << S_FW_FILTER_WR_DROP)
173#define G_FW_FILTER_WR_DROP(x) \
174 (((x) >> S_FW_FILTER_WR_DROP) & M_FW_FILTER_WR_DROP)
175#define F_FW_FILTER_WR_DROP V_FW_FILTER_WR_DROP(1U)
176
177#define S_FW_FILTER_WR_DIRSTEER 23
178#define M_FW_FILTER_WR_DIRSTEER 0x1
179#define V_FW_FILTER_WR_DIRSTEER(x) ((x) << S_FW_FILTER_WR_DIRSTEER)
180#define G_FW_FILTER_WR_DIRSTEER(x) \
181 (((x) >> S_FW_FILTER_WR_DIRSTEER) & M_FW_FILTER_WR_DIRSTEER)
182#define F_FW_FILTER_WR_DIRSTEER V_FW_FILTER_WR_DIRSTEER(1U)
183
184#define S_FW_FILTER_WR_MASKHASH 22
185#define M_FW_FILTER_WR_MASKHASH 0x1
186#define V_FW_FILTER_WR_MASKHASH(x) ((x) << S_FW_FILTER_WR_MASKHASH)
187#define G_FW_FILTER_WR_MASKHASH(x) \
188 (((x) >> S_FW_FILTER_WR_MASKHASH) & M_FW_FILTER_WR_MASKHASH)
189#define F_FW_FILTER_WR_MASKHASH V_FW_FILTER_WR_MASKHASH(1U)
190
191#define S_FW_FILTER_WR_DIRSTEERHASH 21
192#define M_FW_FILTER_WR_DIRSTEERHASH 0x1
193#define V_FW_FILTER_WR_DIRSTEERHASH(x) ((x) << S_FW_FILTER_WR_DIRSTEERHASH)
194#define G_FW_FILTER_WR_DIRSTEERHASH(x) \
195 (((x) >> S_FW_FILTER_WR_DIRSTEERHASH) & M_FW_FILTER_WR_DIRSTEERHASH)
196#define F_FW_FILTER_WR_DIRSTEERHASH V_FW_FILTER_WR_DIRSTEERHASH(1U)
197
198#define S_FW_FILTER_WR_LPBK 20
199#define M_FW_FILTER_WR_LPBK 0x1
200#define V_FW_FILTER_WR_LPBK(x) ((x) << S_FW_FILTER_WR_LPBK)
201#define G_FW_FILTER_WR_LPBK(x) \
202 (((x) >> S_FW_FILTER_WR_LPBK) & M_FW_FILTER_WR_LPBK)
203#define F_FW_FILTER_WR_LPBK V_FW_FILTER_WR_LPBK(1U)
204
205#define S_FW_FILTER_WR_DMAC 19
206#define M_FW_FILTER_WR_DMAC 0x1
207#define V_FW_FILTER_WR_DMAC(x) ((x) << S_FW_FILTER_WR_DMAC)
208#define G_FW_FILTER_WR_DMAC(x) \
209 (((x) >> S_FW_FILTER_WR_DMAC) & M_FW_FILTER_WR_DMAC)
210#define F_FW_FILTER_WR_DMAC V_FW_FILTER_WR_DMAC(1U)
211
212#define S_FW_FILTER_WR_SMAC 18
213#define M_FW_FILTER_WR_SMAC 0x1
214#define V_FW_FILTER_WR_SMAC(x) ((x) << S_FW_FILTER_WR_SMAC)
215#define G_FW_FILTER_WR_SMAC(x) \
216 (((x) >> S_FW_FILTER_WR_SMAC) & M_FW_FILTER_WR_SMAC)
217#define F_FW_FILTER_WR_SMAC V_FW_FILTER_WR_SMAC(1U)
218
219#define S_FW_FILTER_WR_INSVLAN 17
220#define M_FW_FILTER_WR_INSVLAN 0x1
221#define V_FW_FILTER_WR_INSVLAN(x) ((x) << S_FW_FILTER_WR_INSVLAN)
222#define G_FW_FILTER_WR_INSVLAN(x) \
223 (((x) >> S_FW_FILTER_WR_INSVLAN) & M_FW_FILTER_WR_INSVLAN)
224#define F_FW_FILTER_WR_INSVLAN V_FW_FILTER_WR_INSVLAN(1U)
225
226#define S_FW_FILTER_WR_RMVLAN 16
227#define M_FW_FILTER_WR_RMVLAN 0x1
228#define V_FW_FILTER_WR_RMVLAN(x) ((x) << S_FW_FILTER_WR_RMVLAN)
229#define G_FW_FILTER_WR_RMVLAN(x) \
230 (((x) >> S_FW_FILTER_WR_RMVLAN) & M_FW_FILTER_WR_RMVLAN)
231#define F_FW_FILTER_WR_RMVLAN V_FW_FILTER_WR_RMVLAN(1U)
232
233#define S_FW_FILTER_WR_HITCNTS 15
234#define M_FW_FILTER_WR_HITCNTS 0x1
235#define V_FW_FILTER_WR_HITCNTS(x) ((x) << S_FW_FILTER_WR_HITCNTS)
236#define G_FW_FILTER_WR_HITCNTS(x) \
237 (((x) >> S_FW_FILTER_WR_HITCNTS) & M_FW_FILTER_WR_HITCNTS)
238#define F_FW_FILTER_WR_HITCNTS V_FW_FILTER_WR_HITCNTS(1U)
239
240#define S_FW_FILTER_WR_TXCHAN 13
241#define M_FW_FILTER_WR_TXCHAN 0x3
242#define V_FW_FILTER_WR_TXCHAN(x) ((x) << S_FW_FILTER_WR_TXCHAN)
243#define G_FW_FILTER_WR_TXCHAN(x) \
244 (((x) >> S_FW_FILTER_WR_TXCHAN) & M_FW_FILTER_WR_TXCHAN)
245
246#define S_FW_FILTER_WR_PRIO 12
247#define M_FW_FILTER_WR_PRIO 0x1
248#define V_FW_FILTER_WR_PRIO(x) ((x) << S_FW_FILTER_WR_PRIO)
249#define G_FW_FILTER_WR_PRIO(x) \
250 (((x) >> S_FW_FILTER_WR_PRIO) & M_FW_FILTER_WR_PRIO)
251#define F_FW_FILTER_WR_PRIO V_FW_FILTER_WR_PRIO(1U)
252
253#define S_FW_FILTER_WR_L2TIX 0
254#define M_FW_FILTER_WR_L2TIX 0xfff
255#define V_FW_FILTER_WR_L2TIX(x) ((x) << S_FW_FILTER_WR_L2TIX)
256#define G_FW_FILTER_WR_L2TIX(x) \
257 (((x) >> S_FW_FILTER_WR_L2TIX) & M_FW_FILTER_WR_L2TIX)
258
259#define S_FW_FILTER_WR_FRAG 7
260#define M_FW_FILTER_WR_FRAG 0x1
261#define V_FW_FILTER_WR_FRAG(x) ((x) << S_FW_FILTER_WR_FRAG)
262#define G_FW_FILTER_WR_FRAG(x) \
263 (((x) >> S_FW_FILTER_WR_FRAG) & M_FW_FILTER_WR_FRAG)
264#define F_FW_FILTER_WR_FRAG V_FW_FILTER_WR_FRAG(1U)
265
266#define S_FW_FILTER_WR_FRAGM 6
267#define M_FW_FILTER_WR_FRAGM 0x1
268#define V_FW_FILTER_WR_FRAGM(x) ((x) << S_FW_FILTER_WR_FRAGM)
269#define G_FW_FILTER_WR_FRAGM(x) \
270 (((x) >> S_FW_FILTER_WR_FRAGM) & M_FW_FILTER_WR_FRAGM)
271#define F_FW_FILTER_WR_FRAGM V_FW_FILTER_WR_FRAGM(1U)
272
273#define S_FW_FILTER_WR_IVLAN_VLD 5
274#define M_FW_FILTER_WR_IVLAN_VLD 0x1
275#define V_FW_FILTER_WR_IVLAN_VLD(x) ((x) << S_FW_FILTER_WR_IVLAN_VLD)
276#define G_FW_FILTER_WR_IVLAN_VLD(x) \
277 (((x) >> S_FW_FILTER_WR_IVLAN_VLD) & M_FW_FILTER_WR_IVLAN_VLD)
278#define F_FW_FILTER_WR_IVLAN_VLD V_FW_FILTER_WR_IVLAN_VLD(1U)
279
280#define S_FW_FILTER_WR_OVLAN_VLD 4
281#define M_FW_FILTER_WR_OVLAN_VLD 0x1
282#define V_FW_FILTER_WR_OVLAN_VLD(x) ((x) << S_FW_FILTER_WR_OVLAN_VLD)
283#define G_FW_FILTER_WR_OVLAN_VLD(x) \
284 (((x) >> S_FW_FILTER_WR_OVLAN_VLD) & M_FW_FILTER_WR_OVLAN_VLD)
285#define F_FW_FILTER_WR_OVLAN_VLD V_FW_FILTER_WR_OVLAN_VLD(1U)
286
287#define S_FW_FILTER_WR_IVLAN_VLDM 3
288#define M_FW_FILTER_WR_IVLAN_VLDM 0x1
289#define V_FW_FILTER_WR_IVLAN_VLDM(x) ((x) << S_FW_FILTER_WR_IVLAN_VLDM)
290#define G_FW_FILTER_WR_IVLAN_VLDM(x) \
291 (((x) >> S_FW_FILTER_WR_IVLAN_VLDM) & M_FW_FILTER_WR_IVLAN_VLDM)
292#define F_FW_FILTER_WR_IVLAN_VLDM V_FW_FILTER_WR_IVLAN_VLDM(1U)
293
294#define S_FW_FILTER_WR_OVLAN_VLDM 2
295#define M_FW_FILTER_WR_OVLAN_VLDM 0x1
296#define V_FW_FILTER_WR_OVLAN_VLDM(x) ((x) << S_FW_FILTER_WR_OVLAN_VLDM)
297#define G_FW_FILTER_WR_OVLAN_VLDM(x) \
298 (((x) >> S_FW_FILTER_WR_OVLAN_VLDM) & M_FW_FILTER_WR_OVLAN_VLDM)
299#define F_FW_FILTER_WR_OVLAN_VLDM V_FW_FILTER_WR_OVLAN_VLDM(1U)
300
301#define S_FW_FILTER_WR_RX_CHAN 15
302#define M_FW_FILTER_WR_RX_CHAN 0x1
303#define V_FW_FILTER_WR_RX_CHAN(x) ((x) << S_FW_FILTER_WR_RX_CHAN)
304#define G_FW_FILTER_WR_RX_CHAN(x) \
305 (((x) >> S_FW_FILTER_WR_RX_CHAN) & M_FW_FILTER_WR_RX_CHAN)
306#define F_FW_FILTER_WR_RX_CHAN V_FW_FILTER_WR_RX_CHAN(1U)
307
308#define S_FW_FILTER_WR_RX_RPL_IQ 0
309#define M_FW_FILTER_WR_RX_RPL_IQ 0x3ff
310#define V_FW_FILTER_WR_RX_RPL_IQ(x) ((x) << S_FW_FILTER_WR_RX_RPL_IQ)
311#define G_FW_FILTER_WR_RX_RPL_IQ(x) \
312 (((x) >> S_FW_FILTER_WR_RX_RPL_IQ) & M_FW_FILTER_WR_RX_RPL_IQ)
313
314#define S_FW_FILTER_WR_MACI 23
315#define M_FW_FILTER_WR_MACI 0x1ff
316#define V_FW_FILTER_WR_MACI(x) ((x) << S_FW_FILTER_WR_MACI)
317#define G_FW_FILTER_WR_MACI(x) \
318 (((x) >> S_FW_FILTER_WR_MACI) & M_FW_FILTER_WR_MACI)
319
320#define S_FW_FILTER_WR_MACIM 14
321#define M_FW_FILTER_WR_MACIM 0x1ff
322#define V_FW_FILTER_WR_MACIM(x) ((x) << S_FW_FILTER_WR_MACIM)
323#define G_FW_FILTER_WR_MACIM(x) \
324 (((x) >> S_FW_FILTER_WR_MACIM) & M_FW_FILTER_WR_MACIM)
325
326#define S_FW_FILTER_WR_FCOE 13
327#define M_FW_FILTER_WR_FCOE 0x1
328#define V_FW_FILTER_WR_FCOE(x) ((x) << S_FW_FILTER_WR_FCOE)
329#define G_FW_FILTER_WR_FCOE(x) \
330 (((x) >> S_FW_FILTER_WR_FCOE) & M_FW_FILTER_WR_FCOE)
331#define F_FW_FILTER_WR_FCOE V_FW_FILTER_WR_FCOE(1U)
332
333#define S_FW_FILTER_WR_FCOEM 12
334#define M_FW_FILTER_WR_FCOEM 0x1
335#define V_FW_FILTER_WR_FCOEM(x) ((x) << S_FW_FILTER_WR_FCOEM)
336#define G_FW_FILTER_WR_FCOEM(x) \
337 (((x) >> S_FW_FILTER_WR_FCOEM) & M_FW_FILTER_WR_FCOEM)
338#define F_FW_FILTER_WR_FCOEM V_FW_FILTER_WR_FCOEM(1U)
339
340#define S_FW_FILTER_WR_PORT 9
341#define M_FW_FILTER_WR_PORT 0x7
342#define V_FW_FILTER_WR_PORT(x) ((x) << S_FW_FILTER_WR_PORT)
343#define G_FW_FILTER_WR_PORT(x) \
344 (((x) >> S_FW_FILTER_WR_PORT) & M_FW_FILTER_WR_PORT)
345
346#define S_FW_FILTER_WR_PORTM 6
347#define M_FW_FILTER_WR_PORTM 0x7
348#define V_FW_FILTER_WR_PORTM(x) ((x) << S_FW_FILTER_WR_PORTM)
349#define G_FW_FILTER_WR_PORTM(x) \
350 (((x) >> S_FW_FILTER_WR_PORTM) & M_FW_FILTER_WR_PORTM)
351
352#define S_FW_FILTER_WR_MATCHTYPE 3
353#define M_FW_FILTER_WR_MATCHTYPE 0x7
354#define V_FW_FILTER_WR_MATCHTYPE(x) ((x) << S_FW_FILTER_WR_MATCHTYPE)
355#define G_FW_FILTER_WR_MATCHTYPE(x) \
356 (((x) >> S_FW_FILTER_WR_MATCHTYPE) & M_FW_FILTER_WR_MATCHTYPE)
357
358#define S_FW_FILTER_WR_MATCHTYPEM 0
359#define M_FW_FILTER_WR_MATCHTYPEM 0x7
360#define V_FW_FILTER_WR_MATCHTYPEM(x) ((x) << S_FW_FILTER_WR_MATCHTYPEM)
361#define G_FW_FILTER_WR_MATCHTYPEM(x) \
362 (((x) >> S_FW_FILTER_WR_MATCHTYPEM) & M_FW_FILTER_WR_MATCHTYPEM)
363
85struct fw_ulptx_wr { 364struct fw_ulptx_wr {
86 __be32 op_to_compl; 365 __be32 op_to_compl;
87 __be32 flowid_len16; 366 __be32 flowid_len16;