|
@@ -710,7 +710,7 @@ static void start_txq(struct net_device *netdev)
|
|
|
{
|
|
|
struct lio *lio = GET_LIO(netdev);
|
|
|
|
|
|
- if (lio->linfo.link.s.status) {
|
|
|
+ if (lio->linfo.link.s.link_up) {
|
|
|
txqs_start(netdev);
|
|
|
return;
|
|
|
}
|
|
@@ -918,7 +918,7 @@ static void print_link_info(struct net_device *netdev)
|
|
|
if (atomic_read(&lio->ifstate) & LIO_IFSTATE_REGISTERED) {
|
|
|
struct oct_link_info *linfo = &lio->linfo;
|
|
|
|
|
|
- if (linfo->link.s.status) {
|
|
|
+ if (linfo->link.s.link_up) {
|
|
|
netif_info(lio, link, lio->netdev, "%d Mbps %s Duplex UP\n",
|
|
|
linfo->link.s.speed,
|
|
|
(linfo->link.s.duplex) ? "Full" : "Half");
|
|
@@ -940,13 +940,15 @@ static inline void update_link_status(struct net_device *netdev,
|
|
|
union oct_link_status *ls)
|
|
|
{
|
|
|
struct lio *lio = GET_LIO(netdev);
|
|
|
+ int changed = (lio->linfo.link.u64 != ls->u64);
|
|
|
|
|
|
- if ((lio->intf_open) && (lio->linfo.link.u64 != ls->u64)) {
|
|
|
- lio->linfo.link.u64 = ls->u64;
|
|
|
+ lio->linfo.link.u64 = ls->u64;
|
|
|
|
|
|
+ if ((lio->intf_open) && (changed)) {
|
|
|
print_link_info(netdev);
|
|
|
+ lio->link_changes++;
|
|
|
|
|
|
- if (lio->linfo.link.s.status) {
|
|
|
+ if (lio->linfo.link.s.link_up) {
|
|
|
netif_carrier_on(netdev);
|
|
|
/* start_txq(netdev); */
|
|
|
txqs_wake(netdev);
|
|
@@ -1219,18 +1221,15 @@ static void octeon_destroy_resources(struct octeon_device *oct)
|
|
|
static void send_rx_ctrl_cmd(struct lio *lio, int start_stop)
|
|
|
{
|
|
|
struct octnic_ctrl_pkt nctrl;
|
|
|
- struct octnic_ctrl_params nparams;
|
|
|
|
|
|
memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
|
|
|
|
|
|
nctrl.ncmd.s.cmd = OCTNET_CMD_RX_CTL;
|
|
|
- nctrl.ncmd.s.param1 = lio->linfo.ifidx;
|
|
|
- nctrl.ncmd.s.param2 = start_stop;
|
|
|
+ nctrl.ncmd.s.param1 = start_stop;
|
|
|
+ nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
|
|
|
nctrl.netpndev = (u64)lio->netdev;
|
|
|
|
|
|
- nparams.resp_order = OCTEON_RESP_NORESPONSE;
|
|
|
-
|
|
|
- if (octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams) < 0)
|
|
|
+ if (octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl) < 0)
|
|
|
netif_info(lio, rx_err, lio->netdev, "Failed to send RX Control message\n");
|
|
|
}
|
|
|
|
|
@@ -1269,6 +1268,8 @@ static void liquidio_destroy_nic_device(struct octeon_device *oct, int ifidx)
|
|
|
|
|
|
free_netdev(netdev);
|
|
|
|
|
|
+ oct->props[ifidx].gmxport = -1;
|
|
|
+
|
|
|
oct->props[ifidx].netdev = NULL;
|
|
|
}
|
|
|
|
|
@@ -1833,21 +1834,21 @@ static u16 select_q(struct net_device *dev, struct sk_buff *skb,
|
|
|
* @param len - size of total data received.
|
|
|
* @param rh - Control header associated with the packet
|
|
|
* @param param - additional control data with the packet
|
|
|
+ * @param arg - farg registered in droq_ops
|
|
|
*/
|
|
|
static void
|
|
|
liquidio_push_packet(u32 octeon_id,
|
|
|
void *skbuff,
|
|
|
u32 len,
|
|
|
union octeon_rh *rh,
|
|
|
- void *param)
|
|
|
+ void *param,
|
|
|
+ void *arg)
|
|
|
{
|
|
|
struct napi_struct *napi = param;
|
|
|
- struct octeon_device *oct = lio_get_device(octeon_id);
|
|
|
struct sk_buff *skb = (struct sk_buff *)skbuff;
|
|
|
struct skb_shared_hwtstamps *shhwtstamps;
|
|
|
u64 ns;
|
|
|
- struct net_device *netdev =
|
|
|
- (struct net_device *)oct->props[rh->r_dh.link].netdev;
|
|
|
+ struct net_device *netdev = (struct net_device *)arg;
|
|
|
struct octeon_droq *droq = container_of(param, struct octeon_droq,
|
|
|
napi);
|
|
|
if (netdev) {
|
|
@@ -2043,10 +2044,10 @@ static int liquidio_napi_poll(struct napi_struct *napi, int budget)
|
|
|
* are for ingress packets.
|
|
|
*/
|
|
|
static inline int setup_io_queues(struct octeon_device *octeon_dev,
|
|
|
- struct net_device *net_device)
|
|
|
+ int ifidx)
|
|
|
{
|
|
|
- static int first_time = 1;
|
|
|
- static struct octeon_droq_ops droq_ops;
|
|
|
+ struct octeon_droq_ops droq_ops;
|
|
|
+ struct net_device *netdev;
|
|
|
static int cpu_id;
|
|
|
static int cpu_id_modulus;
|
|
|
struct octeon_droq *droq;
|
|
@@ -2055,18 +2056,19 @@ static inline int setup_io_queues(struct octeon_device *octeon_dev,
|
|
|
struct lio *lio;
|
|
|
int num_tx_descs;
|
|
|
|
|
|
- lio = GET_LIO(net_device);
|
|
|
- if (first_time) {
|
|
|
- first_time = 0;
|
|
|
- memset(&droq_ops, 0, sizeof(struct octeon_droq_ops));
|
|
|
+ netdev = octeon_dev->props[ifidx].netdev;
|
|
|
+
|
|
|
+ lio = GET_LIO(netdev);
|
|
|
|
|
|
- droq_ops.fptr = liquidio_push_packet;
|
|
|
+ memset(&droq_ops, 0, sizeof(struct octeon_droq_ops));
|
|
|
|
|
|
- droq_ops.poll_mode = 1;
|
|
|
- droq_ops.napi_fn = liquidio_napi_drv_callback;
|
|
|
- cpu_id = 0;
|
|
|
- cpu_id_modulus = num_present_cpus();
|
|
|
- }
|
|
|
+ droq_ops.fptr = liquidio_push_packet;
|
|
|
+ droq_ops.farg = (void *)netdev;
|
|
|
+
|
|
|
+ droq_ops.poll_mode = 1;
|
|
|
+ droq_ops.napi_fn = liquidio_napi_drv_callback;
|
|
|
+ cpu_id = 0;
|
|
|
+ cpu_id_modulus = num_present_cpus();
|
|
|
|
|
|
/* set up DROQs. */
|
|
|
for (q = 0; q < lio->linfo.num_rxpciq; q++) {
|
|
@@ -2090,7 +2092,11 @@ static inline int setup_io_queues(struct octeon_device *octeon_dev,
|
|
|
|
|
|
droq = octeon_dev->droq[q_no];
|
|
|
napi = &droq->napi;
|
|
|
- netif_napi_add(net_device, napi, liquidio_napi_poll, 64);
|
|
|
+ dev_dbg(&octeon_dev->pci_dev->dev,
|
|
|
+ "netif_napi_add netdev:%llx oct:%llx\n",
|
|
|
+ (u64)netdev,
|
|
|
+ (u64)octeon_dev);
|
|
|
+ netif_napi_add(netdev, napi, liquidio_napi_poll, 64);
|
|
|
|
|
|
/* designate a CPU for this droq */
|
|
|
droq->cpu_id = cpu_id;
|
|
@@ -2106,9 +2112,9 @@ static inline int setup_io_queues(struct octeon_device *octeon_dev,
|
|
|
num_tx_descs = CFG_GET_NUM_TX_DESCS_NIC_IF(octeon_get_conf
|
|
|
(octeon_dev),
|
|
|
lio->ifidx);
|
|
|
- retval = octeon_setup_iq(octeon_dev, lio->linfo.txpciq[q],
|
|
|
- num_tx_descs,
|
|
|
- netdev_get_tx_queue(net_device, q));
|
|
|
+ retval = octeon_setup_iq(octeon_dev, ifidx, q,
|
|
|
+ lio->linfo.txpciq[q], num_tx_descs,
|
|
|
+ netdev_get_tx_queue(netdev, q));
|
|
|
if (retval) {
|
|
|
dev_err(&octeon_dev->pci_dev->dev,
|
|
|
" %s : Runtime IQ(TxQ) creation failed.\n",
|
|
@@ -2206,7 +2212,8 @@ static int liquidio_stop(struct net_device *netdev)
|
|
|
netif_info(lio, ifdown, lio->netdev, "Stopping interface!\n");
|
|
|
/* Inform that netif carrier is down */
|
|
|
lio->intf_open = 0;
|
|
|
- lio->linfo.link.s.status = 0;
|
|
|
+ lio->linfo.link.s.link_up = 0;
|
|
|
+ lio->link_changes++;
|
|
|
|
|
|
netif_carrier_off(netdev);
|
|
|
|
|
@@ -2345,7 +2352,6 @@ static void liquidio_set_mcast_list(struct net_device *netdev)
|
|
|
struct lio *lio = GET_LIO(netdev);
|
|
|
struct octeon_device *oct = lio->oct_dev;
|
|
|
struct octnic_ctrl_pkt nctrl;
|
|
|
- struct octnic_ctrl_params nparams;
|
|
|
struct netdev_hw_addr *ha;
|
|
|
u64 *mc;
|
|
|
int ret, i;
|
|
@@ -2356,10 +2362,10 @@ static void liquidio_set_mcast_list(struct net_device *netdev)
|
|
|
/* Create a ctrl pkt command to be sent to core app. */
|
|
|
nctrl.ncmd.u64 = 0;
|
|
|
nctrl.ncmd.s.cmd = OCTNET_CMD_SET_MULTI_LIST;
|
|
|
- nctrl.ncmd.s.param1 = lio->linfo.ifidx;
|
|
|
- nctrl.ncmd.s.param2 = get_new_flags(netdev);
|
|
|
- nctrl.ncmd.s.param3 = mc_count;
|
|
|
+ nctrl.ncmd.s.param1 = get_new_flags(netdev);
|
|
|
+ nctrl.ncmd.s.param2 = mc_count;
|
|
|
nctrl.ncmd.s.more = mc_count;
|
|
|
+ nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
|
|
|
nctrl.netpndev = (u64)netdev;
|
|
|
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
|
|
|
|
|
@@ -2380,9 +2386,7 @@ static void liquidio_set_mcast_list(struct net_device *netdev)
|
|
|
*/
|
|
|
nctrl.wait_time = 0;
|
|
|
|
|
|
- nparams.resp_order = OCTEON_RESP_NORESPONSE;
|
|
|
-
|
|
|
- ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams);
|
|
|
+ ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
|
|
|
if (ret < 0) {
|
|
|
dev_err(&oct->pci_dev->dev, "DEVFLAGS change failed in core (ret: 0x%x)\n",
|
|
|
ret);
|
|
@@ -2400,19 +2404,17 @@ static int liquidio_set_mac(struct net_device *netdev, void *p)
|
|
|
struct octeon_device *oct = lio->oct_dev;
|
|
|
struct sockaddr *addr = (struct sockaddr *)p;
|
|
|
struct octnic_ctrl_pkt nctrl;
|
|
|
- struct octnic_ctrl_params nparams;
|
|
|
|
|
|
- if ((!is_valid_ether_addr(addr->sa_data)) ||
|
|
|
- (ifstate_check(lio, LIO_IFSTATE_RUNNING)))
|
|
|
+ if (!is_valid_ether_addr(addr->sa_data))
|
|
|
return -EADDRNOTAVAIL;
|
|
|
|
|
|
memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
|
|
|
|
|
|
nctrl.ncmd.u64 = 0;
|
|
|
nctrl.ncmd.s.cmd = OCTNET_CMD_CHANGE_MACADDR;
|
|
|
- nctrl.ncmd.s.param1 = lio->linfo.ifidx;
|
|
|
- nctrl.ncmd.s.param2 = 0;
|
|
|
+ nctrl.ncmd.s.param1 = 0;
|
|
|
nctrl.ncmd.s.more = 1;
|
|
|
+ nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
|
|
|
nctrl.netpndev = (u64)netdev;
|
|
|
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
|
|
|
nctrl.wait_time = 100;
|
|
@@ -2421,9 +2423,7 @@ static int liquidio_set_mac(struct net_device *netdev, void *p)
|
|
|
/* The MAC Address is presented in network byte order. */
|
|
|
memcpy((u8 *)&nctrl.udd[0] + 2, addr->sa_data, ETH_ALEN);
|
|
|
|
|
|
- nparams.resp_order = OCTEON_RESP_ORDERED;
|
|
|
-
|
|
|
- ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams);
|
|
|
+ ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
|
|
|
if (ret < 0) {
|
|
|
dev_err(&oct->pci_dev->dev, "MAC Address change failed\n");
|
|
|
return -ENOMEM;
|
|
@@ -2493,7 +2493,6 @@ static int liquidio_change_mtu(struct net_device *netdev, int new_mtu)
|
|
|
struct lio *lio = GET_LIO(netdev);
|
|
|
struct octeon_device *oct = lio->oct_dev;
|
|
|
struct octnic_ctrl_pkt nctrl;
|
|
|
- struct octnic_ctrl_params nparams;
|
|
|
int max_frm_size = new_mtu + OCTNET_FRM_HEADER_SIZE;
|
|
|
int ret = 0;
|
|
|
|
|
@@ -2513,15 +2512,13 @@ static int liquidio_change_mtu(struct net_device *netdev, int new_mtu)
|
|
|
|
|
|
nctrl.ncmd.u64 = 0;
|
|
|
nctrl.ncmd.s.cmd = OCTNET_CMD_CHANGE_MTU;
|
|
|
- nctrl.ncmd.s.param1 = lio->linfo.ifidx;
|
|
|
- nctrl.ncmd.s.param2 = new_mtu;
|
|
|
+ nctrl.ncmd.s.param1 = new_mtu;
|
|
|
+ nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
|
|
|
nctrl.wait_time = 100;
|
|
|
nctrl.netpndev = (u64)netdev;
|
|
|
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
|
|
|
|
|
|
- nparams.resp_order = OCTEON_RESP_ORDERED;
|
|
|
-
|
|
|
- ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams);
|
|
|
+ ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
|
|
|
if (ret < 0) {
|
|
|
dev_err(&oct->pci_dev->dev, "Failed to set MTU\n");
|
|
|
return -1;
|
|
@@ -2742,11 +2739,11 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
|
|
|
* transmitted.
|
|
|
*/
|
|
|
if (!(atomic_read(&lio->ifstate) & LIO_IFSTATE_RUNNING) ||
|
|
|
- (!lio->linfo.link.s.status) ||
|
|
|
+ (!lio->linfo.link.s.link_up) ||
|
|
|
(skb->len <= 0)) {
|
|
|
netif_info(lio, tx_err, lio->netdev,
|
|
|
"Transmit failed link_status : %d\n",
|
|
|
- lio->linfo.link.s.status);
|
|
|
+ lio->linfo.link.s.link_up);
|
|
|
goto lio_xmit_failed;
|
|
|
}
|
|
|
|
|
@@ -2789,7 +2786,6 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
|
|
|
ndata.datasize = skb->len;
|
|
|
|
|
|
cmdsetup.u64 = 0;
|
|
|
- cmdsetup.s.ifidx = lio->linfo.ifidx;
|
|
|
cmdsetup.s.iq_no = iq_no;
|
|
|
|
|
|
if (skb->ip_summed == CHECKSUM_PARTIAL)
|
|
@@ -2802,7 +2798,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
|
|
|
|
|
|
if (skb_shinfo(skb)->nr_frags == 0) {
|
|
|
cmdsetup.s.u.datasize = skb->len;
|
|
|
- octnet_prepare_pci_cmd(&ndata.cmd, &cmdsetup, tag);
|
|
|
+ octnet_prepare_pci_cmd(oct, &ndata.cmd, &cmdsetup, tag);
|
|
|
/* Offload checksum calculation for TCP/UDP packets */
|
|
|
ndata.cmd.dptr = dma_map_single(&oct->pci_dev->dev,
|
|
|
skb->data,
|
|
@@ -2836,7 +2832,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
|
|
|
|
|
|
cmdsetup.s.gather = 1;
|
|
|
cmdsetup.s.u.gatherptrs = (skb_shinfo(skb)->nr_frags + 1);
|
|
|
- octnet_prepare_pci_cmd(&ndata.cmd, &cmdsetup, tag);
|
|
|
+ octnet_prepare_pci_cmd(oct, &ndata.cmd, &cmdsetup, tag);
|
|
|
|
|
|
memset(g->sg, 0, g->sg_size);
|
|
|
|
|
@@ -2952,27 +2948,24 @@ static void liquidio_tx_timeout(struct net_device *netdev)
|
|
|
txqs_wake(netdev);
|
|
|
}
|
|
|
|
|
|
-int liquidio_set_feature(struct net_device *netdev, int cmd)
|
|
|
+int liquidio_set_feature(struct net_device *netdev, int cmd, u16 param1)
|
|
|
{
|
|
|
struct lio *lio = GET_LIO(netdev);
|
|
|
struct octeon_device *oct = lio->oct_dev;
|
|
|
struct octnic_ctrl_pkt nctrl;
|
|
|
- struct octnic_ctrl_params nparams;
|
|
|
int ret = 0;
|
|
|
|
|
|
memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
|
|
|
|
|
|
nctrl.ncmd.u64 = 0;
|
|
|
nctrl.ncmd.s.cmd = cmd;
|
|
|
- nctrl.ncmd.s.param1 = lio->linfo.ifidx;
|
|
|
- nctrl.ncmd.s.param2 = OCTNIC_LROIPV4 | OCTNIC_LROIPV6;
|
|
|
+ nctrl.ncmd.s.param1 = param1;
|
|
|
+ nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
|
|
|
nctrl.wait_time = 100;
|
|
|
nctrl.netpndev = (u64)netdev;
|
|
|
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
|
|
|
|
|
|
- nparams.resp_order = OCTEON_RESP_NORESPONSE;
|
|
|
-
|
|
|
- ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams);
|
|
|
+ ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
|
|
|
if (ret < 0) {
|
|
|
dev_err(&oct->pci_dev->dev, "Feature change failed in core (ret: 0x%x)\n",
|
|
|
ret);
|
|
@@ -3028,10 +3021,12 @@ static int liquidio_set_features(struct net_device *netdev,
|
|
|
return 0;
|
|
|
|
|
|
if ((features & NETIF_F_LRO) && (lio->dev_capability & NETIF_F_LRO))
|
|
|
- liquidio_set_feature(netdev, OCTNET_CMD_LRO_ENABLE);
|
|
|
+ liquidio_set_feature(netdev, OCTNET_CMD_LRO_ENABLE,
|
|
|
+ OCTNIC_LROIPV4 | OCTNIC_LROIPV6);
|
|
|
else if (!(features & NETIF_F_LRO) &&
|
|
|
(lio->dev_capability & NETIF_F_LRO))
|
|
|
- liquidio_set_feature(netdev, OCTNET_CMD_LRO_DISABLE);
|
|
|
+ liquidio_set_feature(netdev, OCTNET_CMD_LRO_DISABLE,
|
|
|
+ OCTNIC_LROIPV4 | OCTNIC_LROIPV6);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -3102,24 +3097,27 @@ static int lio_nic_info(struct octeon_recv_info *recv_info, void *buf)
|
|
|
{
|
|
|
struct octeon_device *oct = (struct octeon_device *)buf;
|
|
|
struct octeon_recv_pkt *recv_pkt = recv_info->recv_pkt;
|
|
|
- int ifidx = 0;
|
|
|
+ int gmxport = 0;
|
|
|
union oct_link_status *ls;
|
|
|
int i;
|
|
|
|
|
|
- if ((recv_pkt->buffer_size[0] != sizeof(*ls)) ||
|
|
|
- (recv_pkt->rh.r_nic_info.ifidx > oct->ifcount)) {
|
|
|
+ if (recv_pkt->buffer_size[0] != sizeof(*ls)) {
|
|
|
dev_err(&oct->pci_dev->dev, "Malformed NIC_INFO, len=%d, ifidx=%d\n",
|
|
|
recv_pkt->buffer_size[0],
|
|
|
- recv_pkt->rh.r_nic_info.ifidx);
|
|
|
+ recv_pkt->rh.r_nic_info.gmxport);
|
|
|
goto nic_info_err;
|
|
|
}
|
|
|
|
|
|
- ifidx = recv_pkt->rh.r_nic_info.ifidx;
|
|
|
+ gmxport = recv_pkt->rh.r_nic_info.gmxport;
|
|
|
ls = (union oct_link_status *)get_rbd(recv_pkt->buffer_ptr[0]);
|
|
|
|
|
|
octeon_swap_8B_data((u64 *)ls, (sizeof(union oct_link_status)) >> 3);
|
|
|
-
|
|
|
- update_link_status(oct->props[ifidx].netdev, ls);
|
|
|
+ for (i = 0; i < oct->ifcount; i++) {
|
|
|
+ if (oct->props[i].gmxport == gmxport) {
|
|
|
+ update_link_status(oct->props[i].netdev, ls);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
nic_info_err:
|
|
|
for (i = 0; i < recv_pkt->buffer_count; i++)
|
|
@@ -3146,12 +3144,12 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
|
|
|
struct liquidio_if_cfg_resp *resp;
|
|
|
struct octdev_props *props;
|
|
|
int retval, num_iqueues, num_oqueues;
|
|
|
- u64 q_mask;
|
|
|
int num_cpus = num_online_cpus();
|
|
|
union oct_nic_if_cfg if_cfg;
|
|
|
unsigned int base_queue;
|
|
|
unsigned int gmx_port_id;
|
|
|
u32 resp_size, ctx_size;
|
|
|
+ u32 ifidx_or_pfnum;
|
|
|
|
|
|
/* This is to handle link status changes */
|
|
|
octeon_register_dispatch_fn(octeon_dev, OPCODE_NIC,
|
|
@@ -3187,13 +3185,14 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
|
|
|
CFG_GET_BASE_QUE_NIC_IF(octeon_get_conf(octeon_dev), i);
|
|
|
gmx_port_id =
|
|
|
CFG_GET_GMXID_NIC_IF(octeon_get_conf(octeon_dev), i);
|
|
|
+ ifidx_or_pfnum = i;
|
|
|
if (num_iqueues > num_cpus)
|
|
|
num_iqueues = num_cpus;
|
|
|
if (num_oqueues > num_cpus)
|
|
|
num_oqueues = num_cpus;
|
|
|
dev_dbg(&octeon_dev->pci_dev->dev,
|
|
|
"requesting config for interface %d, iqs %d, oqs %d\n",
|
|
|
- i, num_iqueues, num_oqueues);
|
|
|
+ ifidx_or_pfnum, num_iqueues, num_oqueues);
|
|
|
ACCESS_ONCE(ctx->cond) = 0;
|
|
|
ctx->octeon_id = lio_get_device_id(octeon_dev);
|
|
|
init_waitqueue_head(&ctx->wc);
|
|
@@ -3203,8 +3202,11 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
|
|
|
if_cfg.s.num_oqueues = num_oqueues;
|
|
|
if_cfg.s.base_queue = base_queue;
|
|
|
if_cfg.s.gmx_port_id = gmx_port_id;
|
|
|
+
|
|
|
+ sc->iq_no = 0;
|
|
|
+
|
|
|
octeon_prepare_soft_command(octeon_dev, sc, OPCODE_NIC,
|
|
|
- OPCODE_NIC_IF_CFG, i,
|
|
|
+ OPCODE_NIC_IF_CFG, 0,
|
|
|
if_cfg.u64, 0);
|
|
|
|
|
|
sc->callback = if_cfg_callback;
|
|
@@ -3254,8 +3256,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
|
|
|
goto setup_nic_dev_fail;
|
|
|
}
|
|
|
|
|
|
- props = &octeon_dev->props[i];
|
|
|
- props->netdev = netdev;
|
|
|
+ SET_NETDEV_DEV(netdev, &octeon_dev->pci_dev->dev);
|
|
|
|
|
|
if (num_iqueues > 1)
|
|
|
lionetdevops.ndo_select_queue = select_q;
|
|
@@ -3269,18 +3270,18 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
|
|
|
|
|
|
memset(lio, 0, sizeof(struct lio));
|
|
|
|
|
|
- lio->linfo.ifidx = resp->cfg_info.ifidx;
|
|
|
- lio->ifidx = resp->cfg_info.ifidx;
|
|
|
+ lio->ifidx = ifidx_or_pfnum;
|
|
|
+
|
|
|
+ props = &octeon_dev->props[i];
|
|
|
+ props->gmxport = resp->cfg_info.linfo.gmxport;
|
|
|
+ props->netdev = netdev;
|
|
|
|
|
|
lio->linfo.num_rxpciq = num_oqueues;
|
|
|
lio->linfo.num_txpciq = num_iqueues;
|
|
|
- q_mask = resp->cfg_info.oqmask;
|
|
|
- /* q_mask is 0-based and already verified mask is nonzero */
|
|
|
for (j = 0; j < num_oqueues; j++) {
|
|
|
lio->linfo.rxpciq[j].u64 =
|
|
|
resp->cfg_info.linfo.rxpciq[j].u64;
|
|
|
}
|
|
|
- q_mask = resp->cfg_info.iqmask;
|
|
|
for (j = 0; j < num_iqueues; j++) {
|
|
|
lio->linfo.txpciq[j].u64 =
|
|
|
resp->cfg_info.linfo.txpciq[j].u64;
|
|
@@ -3292,13 +3293,15 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
|
|
|
lio->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
|
|
|
|
|
|
lio->dev_capability = NETIF_F_HIGHDMA
|
|
|
- | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
|
|
|
- | NETIF_F_SG | NETIF_F_RXCSUM
|
|
|
- | NETIF_F_TSO | NETIF_F_TSO6
|
|
|
- | NETIF_F_LRO;
|
|
|
+ | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
|
|
|
+ | NETIF_F_SG | NETIF_F_RXCSUM
|
|
|
+ | NETIF_F_GRO
|
|
|
+ | NETIF_F_TSO | NETIF_F_TSO6
|
|
|
+ | NETIF_F_LRO;
|
|
|
netif_set_gso_max_size(netdev, OCTNIC_GSO_MAX_SIZE);
|
|
|
|
|
|
- netdev->features = lio->dev_capability;
|
|
|
+ netdev->features = (lio->dev_capability & ~NETIF_F_LRO);
|
|
|
+
|
|
|
netdev->vlan_features = lio->dev_capability;
|
|
|
|
|
|
netdev->hw_features = lio->dev_capability;
|
|
@@ -3328,7 +3331,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
|
|
|
*/
|
|
|
lio->txq = lio->linfo.txpciq[0].s.q_no;
|
|
|
lio->rxq = lio->linfo.rxpciq[0].s.q_no;
|
|
|
- if (setup_io_queues(octeon_dev, netdev)) {
|
|
|
+ if (setup_io_queues(octeon_dev, i)) {
|
|
|
dev_err(&octeon_dev->pci_dev->dev, "I/O queues creation failed\n");
|
|
|
goto setup_nic_dev_fail;
|
|
|
}
|
|
@@ -3347,10 +3350,13 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
|
|
|
/* Register ethtool support */
|
|
|
liquidio_set_ethtool_ops(netdev);
|
|
|
|
|
|
- liquidio_set_feature(netdev, OCTNET_CMD_LRO_ENABLE);
|
|
|
+ if (netdev->features & NETIF_F_LRO)
|
|
|
+ liquidio_set_feature(netdev, OCTNET_CMD_LRO_ENABLE,
|
|
|
+ OCTNIC_LROIPV4 | OCTNIC_LROIPV6);
|
|
|
|
|
|
if ((debug != -1) && (debug & NETIF_MSG_HW))
|
|
|
- liquidio_set_feature(netdev, OCTNET_CMD_VERBOSE_ENABLE);
|
|
|
+ liquidio_set_feature(netdev, OCTNET_CMD_VERBOSE_ENABLE,
|
|
|
+ 0);
|
|
|
|
|
|
/* Register the network device with the OS */
|
|
|
if (register_netdev(netdev)) {
|
|
@@ -3362,13 +3368,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
|
|
|
"Setup NIC ifidx:%d mac:%02x%02x%02x%02x%02x%02x\n",
|
|
|
i, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
|
|
netif_carrier_off(netdev);
|
|
|
-
|
|
|
- if (lio->linfo.link.s.status) {
|
|
|
- netif_carrier_on(netdev);
|
|
|
- start_txq(netdev);
|
|
|
- } else {
|
|
|
- netif_carrier_off(netdev);
|
|
|
- }
|
|
|
+ lio->link_changes++;
|
|
|
|
|
|
ifstate_set(lio, LIO_IFSTATE_REGISTERED);
|
|
|
|
|
@@ -3402,7 +3402,7 @@ setup_nic_dev_fail:
|
|
|
static int liquidio_init_nic_module(struct octeon_device *oct)
|
|
|
{
|
|
|
struct oct_intrmod_cfg *intrmod_cfg;
|
|
|
- int retval = 0;
|
|
|
+ int i, retval = 0;
|
|
|
int num_nic_ports = CFG_GET_NUM_NIC_PORTS(octeon_get_conf(oct));
|
|
|
|
|
|
dev_dbg(&oct->pci_dev->dev, "Initializing network interfaces\n");
|
|
@@ -3416,6 +3416,9 @@ static int liquidio_init_nic_module(struct octeon_device *oct)
|
|
|
memset(oct->props, 0,
|
|
|
sizeof(struct octdev_props) * num_nic_ports);
|
|
|
|
|
|
+ for (i = 0; i < MAX_OCTEON_LINKS; i++)
|
|
|
+ oct->props[i].gmxport = -1;
|
|
|
+
|
|
|
retval = setup_nic_devices(oct);
|
|
|
if (retval) {
|
|
|
dev_err(&oct->pci_dev->dev, "Setup NIC devices failed\n");
|