diff options
Diffstat (limited to 'drivers/net/cxgb3/cxgb3_main.c')
-rw-r--r-- | drivers/net/cxgb3/cxgb3_main.c | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 804414637ec..7e7ee7ae177 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -649,6 +649,37 @@ static void init_port_mtus(struct adapter *adapter) t3_write_reg(adapter, A_TP_MTU_PORT_TABLE, mtus); } +static void send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo, + int hi, int port) +{ + struct sk_buff *skb; + struct mngt_pktsched_wr *req; + + skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); + req = (struct mngt_pktsched_wr *)skb_put(skb, sizeof(*req)); + req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT)); + req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET; + req->sched = sched; + req->idx = qidx; + req->min = lo; + req->max = hi; + req->binding = port; + t3_mgmt_tx(adap, skb); +} + +static void bind_qsets(struct adapter *adap) +{ + int i, j; + + for_each_port(adap, i) { + const struct port_info *pi = adap2pinfo(adap, i); + + for (j = 0; j < pi->nqsets; ++j) + send_pktsched_cmd(adap, 1, pi->first_qset + j, -1, + -1, i); + } +} + /** * cxgb_up - enable the adapter * @adapter: adapter being enabled @@ -708,6 +739,11 @@ static int cxgb_up(struct adapter *adap) t3_sge_start(adap); t3_intr_enable(adap); + + if ((adap->flags & (USING_MSIX | QUEUES_BOUND)) == USING_MSIX) + bind_qsets(adap); + adap->flags |= QUEUES_BOUND; + out: return err; irq_err: @@ -1830,34 +1866,18 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr) break; } case CHELSIO_SET_PKTSCHED:{ - struct sk_buff *skb; struct ch_pktsched_params p; - struct mngt_pktsched_wr *req; - if (!(adapter->flags & FULL_INIT_DONE)) - return -EIO; /* uP must be up and running */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (!adapter->open_device_map) + return -EAGAIN; /* uP and SGE must be running */ if (copy_from_user(&p, useraddr, sizeof(p))) - return -EFAULT; - skb = alloc_skb(sizeof(*req), GFP_KERNEL); - if (!skb) - return -ENOMEM; - req = - (struct mngt_pktsched_wr *)skb_put(skb, - sizeof(*req)); - req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT)); - req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET; - req->sched = p.sched; - req->idx = p.idx; - req->min = p.min; - req->max = p.max; - req->binding = p.binding; - printk(KERN_INFO - "pktsched: sched %u idx %u min %u max %u binding %u\n", - req->sched, req->idx, req->min, req->max, - req->binding); - skb->priority = 1; - offload_tx(&adapter->tdev, skb); + return -EFAULT; + send_pktsched_cmd(adapter, p.sched, p.idx, p.min, p.max, + p.binding); break; + } default: return -EOPNOTSUPP; |