aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4.h4
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c151
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h15
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_regs.h33
4 files changed, 193 insertions, 10 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 24ce797ddbbd..46ddd432cdf2 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -35,6 +35,8 @@
35#ifndef __CXGB4_H__ 35#ifndef __CXGB4_H__
36#define __CXGB4_H__ 36#define __CXGB4_H__
37 37
38#include "t4_hw.h"
39
38#include <linux/bitops.h> 40#include <linux/bitops.h>
39#include <linux/cache.h> 41#include <linux/cache.h>
40#include <linux/interrupt.h> 42#include <linux/interrupt.h>
@@ -212,6 +214,8 @@ struct tp_err_stats {
212struct tp_params { 214struct tp_params {
213 unsigned int ntxchan; /* # of Tx channels */ 215 unsigned int ntxchan; /* # of Tx channels */
214 unsigned int tre; /* log2 of core clocks per TP tick */ 216 unsigned int tre; /* log2 of core clocks per TP tick */
217 unsigned short tx_modq_map; /* TX modulation scheduler queue to */
218 /* channel map */
215 219
216 uint32_t dack_re; /* DACK timer resolution */ 220 uint32_t dack_re; /* DACK timer resolution */
217 unsigned short tx_modq[NCHAN]; /* channel to modulation queue map */ 221 unsigned short tx_modq[NCHAN]; /* channel to modulation queue map */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 41537a403eef..888bc7fc7a38 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -2481,8 +2481,34 @@ int cxgb4_alloc_stid(struct tid_info *t, int family, void *data)
2481} 2481}
2482EXPORT_SYMBOL(cxgb4_alloc_stid); 2482EXPORT_SYMBOL(cxgb4_alloc_stid);
2483 2483
2484/* 2484/* Allocate a server filter TID and set it to the supplied value.
2485 * Release a server TID. 2485 */
2486int cxgb4_alloc_sftid(struct tid_info *t, int family, void *data)
2487{
2488 int stid;
2489
2490 spin_lock_bh(&t->stid_lock);
2491 if (family == PF_INET) {
2492 stid = find_next_zero_bit(t->stid_bmap,
2493 t->nstids + t->nsftids, t->nstids);
2494 if (stid < (t->nstids + t->nsftids))
2495 __set_bit(stid, t->stid_bmap);
2496 else
2497 stid = -1;
2498 } else {
2499 stid = -1;
2500 }
2501 if (stid >= 0) {
2502 t->stid_tab[stid].data = data;
2503 stid += t->stid_base;
2504 t->stids_in_use++;
2505 }
2506 spin_unlock_bh(&t->stid_lock);
2507 return stid;
2508}
2509EXPORT_SYMBOL(cxgb4_alloc_sftid);
2510
2511/* Release a server TID.
2486 */ 2512 */
2487void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family) 2513void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family)
2488{ 2514{
@@ -2597,12 +2623,14 @@ static int tid_init(struct tid_info *t)
2597 unsigned int stid_bmap_size; 2623 unsigned int stid_bmap_size;
2598 unsigned int natids = t->natids; 2624 unsigned int natids = t->natids;
2599 2625
2600 stid_bmap_size = BITS_TO_LONGS(t->nstids); 2626 stid_bmap_size = BITS_TO_LONGS(t->nstids + t->nsftids);
2601 size = t->ntids * sizeof(*t->tid_tab) + 2627 size = t->ntids * sizeof(*t->tid_tab) +
2602 natids * sizeof(*t->atid_tab) + 2628 natids * sizeof(*t->atid_tab) +
2603 t->nstids * sizeof(*t->stid_tab) + 2629 t->nstids * sizeof(*t->stid_tab) +
2630 t->nsftids * sizeof(*t->stid_tab) +
2604 stid_bmap_size * sizeof(long) + 2631 stid_bmap_size * sizeof(long) +
2605 t->nftids * sizeof(*t->ftid_tab); 2632 t->nftids * sizeof(*t->ftid_tab) +
2633 t->nsftids * sizeof(*t->ftid_tab);
2606 2634
2607 t->tid_tab = t4_alloc_mem(size); 2635 t->tid_tab = t4_alloc_mem(size);
2608 if (!t->tid_tab) 2636 if (!t->tid_tab)
@@ -2610,7 +2638,7 @@ static int tid_init(struct tid_info *t)
2610 2638
2611 t->atid_tab = (union aopen_entry *)&t->tid_tab[t->ntids]; 2639 t->atid_tab = (union aopen_entry *)&t->tid_tab[t->ntids];
2612 t->stid_tab = (struct serv_entry *)&t->atid_tab[natids]; 2640 t->stid_tab = (struct serv_entry *)&t->atid_tab[natids];
2613 t->stid_bmap = (unsigned long *)&t->stid_tab[t->nstids]; 2641 t->stid_bmap = (unsigned long *)&t->stid_tab[t->nstids + t->nsftids];
2614 t->ftid_tab = (struct filter_entry *)&t->stid_bmap[stid_bmap_size]; 2642 t->ftid_tab = (struct filter_entry *)&t->stid_bmap[stid_bmap_size];
2615 spin_lock_init(&t->stid_lock); 2643 spin_lock_init(&t->stid_lock);
2616 spin_lock_init(&t->atid_lock); 2644 spin_lock_init(&t->atid_lock);
@@ -2626,7 +2654,7 @@ static int tid_init(struct tid_info *t)
2626 t->atid_tab[natids - 1].next = &t->atid_tab[natids]; 2654 t->atid_tab[natids - 1].next = &t->atid_tab[natids];
2627 t->afree = t->atid_tab; 2655 t->afree = t->atid_tab;
2628 } 2656 }
2629 bitmap_zero(t->stid_bmap, t->nstids); 2657 bitmap_zero(t->stid_bmap, t->nstids + t->nsftids);
2630 return 0; 2658 return 0;
2631} 2659}
2632 2660
@@ -2988,6 +3016,7 @@ static void uld_attach(struct adapter *adap, unsigned int uld)
2988{ 3016{
2989 void *handle; 3017 void *handle;
2990 struct cxgb4_lld_info lli; 3018 struct cxgb4_lld_info lli;
3019 unsigned short i;
2991 3020
2992 lli.pdev = adap->pdev; 3021 lli.pdev = adap->pdev;
2993 lli.l2t = adap->l2t; 3022 lli.l2t = adap->l2t;
@@ -3014,10 +3043,16 @@ static void uld_attach(struct adapter *adap, unsigned int uld)
3014 lli.ucq_density = 1 << QUEUESPERPAGEPF0_GET( 3043 lli.ucq_density = 1 << QUEUESPERPAGEPF0_GET(
3015 t4_read_reg(adap, SGE_INGRESS_QUEUES_PER_PAGE_PF) >> 3044 t4_read_reg(adap, SGE_INGRESS_QUEUES_PER_PAGE_PF) >>
3016 (adap->fn * 4)); 3045 (adap->fn * 4));
3046 lli.filt_mode = tp_vlan_pri_map;
3047 /* MODQ_REQ_MAP sets queues 0-3 to chan 0-3 */
3048 for (i = 0; i < NCHAN; i++)
3049 lli.tx_modq[i] = i;
3017 lli.gts_reg = adap->regs + MYPF_REG(SGE_PF_GTS); 3050 lli.gts_reg = adap->regs + MYPF_REG(SGE_PF_GTS);
3018 lli.db_reg = adap->regs + MYPF_REG(SGE_PF_KDOORBELL); 3051 lli.db_reg = adap->regs + MYPF_REG(SGE_PF_KDOORBELL);
3019 lli.fw_vers = adap->params.fw_vers; 3052 lli.fw_vers = adap->params.fw_vers;
3020 lli.dbfifo_int_thresh = dbfifo_int_thresh; 3053 lli.dbfifo_int_thresh = dbfifo_int_thresh;
3054 lli.sge_pktshift = adap->sge.pktshift;
3055 lli.enable_fw_ofld_conn = adap->flags & FW_OFLD_CONN;
3021 3056
3022 handle = ulds[uld].add(&lli); 3057 handle = ulds[uld].add(&lli);
3023 if (IS_ERR(handle)) { 3058 if (IS_ERR(handle)) {
@@ -3258,7 +3293,7 @@ static int delete_filter(struct adapter *adapter, unsigned int fidx)
3258 struct filter_entry *f; 3293 struct filter_entry *f;
3259 int ret; 3294 int ret;
3260 3295
3261 if (fidx >= adapter->tids.nftids) 3296 if (fidx >= adapter->tids.nftids + adapter->tids.nsftids)
3262 return -EINVAL; 3297 return -EINVAL;
3263 3298
3264 f = &adapter->tids.ftid_tab[fidx]; 3299 f = &adapter->tids.ftid_tab[fidx];
@@ -3271,6 +3306,77 @@ static int delete_filter(struct adapter *adapter, unsigned int fidx)
3271 return 0; 3306 return 0;
3272} 3307}
3273 3308
3309int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid,
3310 __be32 sip, __be16 sport, unsigned int queue)
3311{
3312 int ret;
3313 struct filter_entry *f;
3314 struct adapter *adap;
3315 int i;
3316 u8 *val;
3317
3318 adap = netdev2adap(dev);
3319
3320 /* Check to make sure the filter requested is writable ...
3321 */
3322 f = &adap->tids.ftid_tab[stid];
3323 ret = writable_filter(f);
3324 if (ret)
3325 return ret;
3326
3327 /* Clear out any old resources being used by the filter before
3328 * we start constructing the new filter.
3329 */
3330 if (f->valid)
3331 clear_filter(adap, f);
3332
3333 /* Clear out filter specifications */
3334 memset(&f->fs, 0, sizeof(struct ch_filter_specification));
3335 f->fs.val.lport = cpu_to_be16(sport);
3336 f->fs.mask.lport = ~0;
3337 val = (u8 *)&sip;
3338 if ((val[0] | val[1] | val[2] | val[3]) != 0)
3339 for (i = 0; i < 4; i++) {
3340 f->fs.val.lip[i] = val[i];
3341 f->fs.mask.lip[i] = ~0;
3342 }
3343
3344 f->fs.dirsteer = 1;
3345 f->fs.iq = queue;
3346 /* Mark filter as locked */
3347 f->locked = 1;
3348 f->fs.rpttid = 1;
3349
3350 ret = set_filter_wr(adap, stid);
3351 if (ret) {
3352 clear_filter(adap, f);
3353 return ret;
3354 }
3355
3356 return 0;
3357}
3358EXPORT_SYMBOL(cxgb4_create_server_filter);
3359
3360int cxgb4_remove_server_filter(const struct net_device *dev, unsigned int stid,
3361 unsigned int queue, bool ipv6)
3362{
3363 int ret;
3364 struct filter_entry *f;
3365 struct adapter *adap;
3366
3367 adap = netdev2adap(dev);
3368 f = &adap->tids.ftid_tab[stid];
3369 /* Unlock the filter */
3370 f->locked = 0;
3371
3372 ret = delete_filter(adap, stid);
3373 if (ret)
3374 return ret;
3375
3376 return 0;
3377}
3378EXPORT_SYMBOL(cxgb4_remove_server_filter);
3379
3274static struct rtnl_link_stats64 *cxgb_get_stats(struct net_device *dev, 3380static struct rtnl_link_stats64 *cxgb_get_stats(struct net_device *dev,
3275 struct rtnl_link_stats64 *ns) 3381 struct rtnl_link_stats64 *ns)
3276{ 3382{
@@ -3517,6 +3623,34 @@ static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c)
3517 v = t4_read_reg(adap, TP_PIO_DATA); 3623 v = t4_read_reg(adap, TP_PIO_DATA);
3518 t4_write_reg(adap, TP_PIO_DATA, v & ~CSUM_HAS_PSEUDO_HDR); 3624 t4_write_reg(adap, TP_PIO_DATA, v & ~CSUM_HAS_PSEUDO_HDR);
3519 3625
3626 /* first 4 Tx modulation queues point to consecutive Tx channels */
3627 adap->params.tp.tx_modq_map = 0xE4;
3628 t4_write_reg(adap, A_TP_TX_MOD_QUEUE_REQ_MAP,
3629 V_TX_MOD_QUEUE_REQ_MAP(adap->params.tp.tx_modq_map));
3630
3631 /* associate each Tx modulation queue with consecutive Tx channels */
3632 v = 0x84218421;
3633 t4_write_indirect(adap, TP_PIO_ADDR, TP_PIO_DATA,
3634 &v, 1, A_TP_TX_SCHED_HDR);
3635 t4_write_indirect(adap, TP_PIO_ADDR, TP_PIO_DATA,
3636 &v, 1, A_TP_TX_SCHED_FIFO);
3637 t4_write_indirect(adap, TP_PIO_ADDR, TP_PIO_DATA,
3638 &v, 1, A_TP_TX_SCHED_PCMD);
3639
3640#define T4_TX_MODQ_10G_WEIGHT_DEFAULT 16 /* in KB units */
3641 if (is_offload(adap)) {
3642 t4_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0,
3643 V_TX_MODQ_WEIGHT0(T4_TX_MODQ_10G_WEIGHT_DEFAULT) |
3644 V_TX_MODQ_WEIGHT1(T4_TX_MODQ_10G_WEIGHT_DEFAULT) |
3645 V_TX_MODQ_WEIGHT2(T4_TX_MODQ_10G_WEIGHT_DEFAULT) |
3646 V_TX_MODQ_WEIGHT3(T4_TX_MODQ_10G_WEIGHT_DEFAULT));
3647 t4_write_reg(adap, A_TP_TX_MOD_CHANNEL_WEIGHT,
3648 V_TX_MODQ_WEIGHT0(T4_TX_MODQ_10G_WEIGHT_DEFAULT) |
3649 V_TX_MODQ_WEIGHT1(T4_TX_MODQ_10G_WEIGHT_DEFAULT) |
3650 V_TX_MODQ_WEIGHT2(T4_TX_MODQ_10G_WEIGHT_DEFAULT) |
3651 V_TX_MODQ_WEIGHT3(T4_TX_MODQ_10G_WEIGHT_DEFAULT));
3652 }
3653
3520 /* get basic stuff going */ 3654 /* get basic stuff going */
3521 return t4_early_init(adap, adap->fn); 3655 return t4_early_init(adap, adap->fn);
3522} 3656}
@@ -4938,7 +5072,8 @@ static void remove_one(struct pci_dev *pdev)
4938 */ 5072 */
4939 if (adapter->tids.ftid_tab) { 5073 if (adapter->tids.ftid_tab) {
4940 struct filter_entry *f = &adapter->tids.ftid_tab[0]; 5074 struct filter_entry *f = &adapter->tids.ftid_tab[0];
4941 for (i = 0; i < adapter->tids.nftids; i++, f++) 5075 for (i = 0; i < (adapter->tids.nftids +
5076 adapter->tids.nsftids); i++, f++)
4942 if (f->valid) 5077 if (f->valid)
4943 clear_filter(adapter, f); 5078 clear_filter(adapter, f);
4944 } 5079 }
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
index 59a61332b78c..065bbd5b2411 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
@@ -131,7 +131,7 @@ static inline void *lookup_atid(const struct tid_info *t, unsigned int atid)
131static inline void *lookup_stid(const struct tid_info *t, unsigned int stid) 131static inline void *lookup_stid(const struct tid_info *t, unsigned int stid)
132{ 132{
133 stid -= t->stid_base; 133 stid -= t->stid_base;
134 return stid < t->nstids ? t->stid_tab[stid].data : NULL; 134 return stid < (t->nstids + t->nsftids) ? t->stid_tab[stid].data : NULL;
135} 135}
136 136
137static inline void cxgb4_insert_tid(struct tid_info *t, void *data, 137static inline void cxgb4_insert_tid(struct tid_info *t, void *data,
@@ -143,6 +143,7 @@ static inline void cxgb4_insert_tid(struct tid_info *t, void *data,
143 143
144int cxgb4_alloc_atid(struct tid_info *t, void *data); 144int cxgb4_alloc_atid(struct tid_info *t, void *data);
145int cxgb4_alloc_stid(struct tid_info *t, int family, void *data); 145int cxgb4_alloc_stid(struct tid_info *t, int family, void *data);
146int cxgb4_alloc_sftid(struct tid_info *t, int family, void *data);
146void cxgb4_free_atid(struct tid_info *t, unsigned int atid); 147void cxgb4_free_atid(struct tid_info *t, unsigned int atid);
147void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family); 148void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family);
148void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid); 149void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid);
@@ -151,7 +152,10 @@ struct in6_addr;
151 152
152int cxgb4_create_server(const struct net_device *dev, unsigned int stid, 153int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
153 __be32 sip, __be16 sport, unsigned int queue); 154 __be32 sip, __be16 sport, unsigned int queue);
154 155int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid,
156 __be32 sip, __be16 sport, unsigned int queue);
157int cxgb4_remove_server_filter(const struct net_device *dev, unsigned int stid,
158 unsigned int queue, bool ipv6);
155static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue) 159static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue)
156{ 160{
157 skb_set_queue_mapping(skb, (queue << 1) | prio); 161 skb_set_queue_mapping(skb, (queue << 1) | prio);
@@ -223,9 +227,16 @@ struct cxgb4_lld_info {
223 unsigned int iscsi_iolen; /* iSCSI max I/O length */ 227 unsigned int iscsi_iolen; /* iSCSI max I/O length */
224 unsigned short udb_density; /* # of user DB/page */ 228 unsigned short udb_density; /* # of user DB/page */
225 unsigned short ucq_density; /* # of user CQs/page */ 229 unsigned short ucq_density; /* # of user CQs/page */
230 unsigned short filt_mode; /* filter optional components */
231 unsigned short tx_modq[NCHAN]; /* maps each tx channel to a */
232 /* scheduler queue */
226 void __iomem *gts_reg; /* address of GTS register */ 233 void __iomem *gts_reg; /* address of GTS register */
227 void __iomem *db_reg; /* address of kernel doorbell */ 234 void __iomem *db_reg; /* address of kernel doorbell */
228 int dbfifo_int_thresh; /* doorbell fifo int threshold */ 235 int dbfifo_int_thresh; /* doorbell fifo int threshold */
236 unsigned int sge_pktshift; /* Padding between CPL and */
237 /* packet data */
238 bool enable_fw_ofld_conn; /* Enable connection through fw */
239 /* WR */
229}; 240};
230 241
231struct cxgb4_uld_info { 242struct cxgb4_uld_info {
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
index 75393f5cff41..aef529198922 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
@@ -1064,4 +1064,37 @@
1064#define ADDRESS(x) ((x) << ADDRESS_SHIFT) 1064#define ADDRESS(x) ((x) << ADDRESS_SHIFT)
1065 1065
1066#define XGMAC_PORT_INT_CAUSE 0x10dc 1066#define XGMAC_PORT_INT_CAUSE 0x10dc
1067
1068#define A_TP_TX_MOD_QUEUE_REQ_MAP 0x7e28
1069
1070#define A_TP_TX_MOD_CHANNEL_WEIGHT 0x7e34
1071
1072#define S_TX_MOD_QUEUE_REQ_MAP 0
1073#define M_TX_MOD_QUEUE_REQ_MAP 0xffffU
1074#define V_TX_MOD_QUEUE_REQ_MAP(x) ((x) << S_TX_MOD_QUEUE_REQ_MAP)
1075
1076#define A_TP_TX_MOD_QUEUE_WEIGHT0 0x7e30
1077
1078#define S_TX_MODQ_WEIGHT3 24
1079#define M_TX_MODQ_WEIGHT3 0xffU
1080#define V_TX_MODQ_WEIGHT3(x) ((x) << S_TX_MODQ_WEIGHT3)
1081
1082#define S_TX_MODQ_WEIGHT2 16
1083#define M_TX_MODQ_WEIGHT2 0xffU
1084#define V_TX_MODQ_WEIGHT2(x) ((x) << S_TX_MODQ_WEIGHT2)
1085
1086#define S_TX_MODQ_WEIGHT1 8
1087#define M_TX_MODQ_WEIGHT1 0xffU
1088#define V_TX_MODQ_WEIGHT1(x) ((x) << S_TX_MODQ_WEIGHT1)
1089
1090#define S_TX_MODQ_WEIGHT0 0
1091#define M_TX_MODQ_WEIGHT0 0xffU
1092#define V_TX_MODQ_WEIGHT0(x) ((x) << S_TX_MODQ_WEIGHT0)
1093
1094#define A_TP_TX_SCHED_HDR 0x23
1095
1096#define A_TP_TX_SCHED_FIFO 0x24
1097
1098#define A_TP_TX_SCHED_PCMD 0x25
1099
1067#endif /* __T4_REGS_H */ 1100#endif /* __T4_REGS_H */