Commit 0cece6c5 authored by Raghu Vatsavayi's avatar Raghu Vatsavayi Committed by David S. Miller

liquidio: Replace ifidx for FW commands

This patch decoupled the firmware side ifidx and host side interface
number. It also has some minor name change for linkinfo sturct field.
Signed-off-by: default avatarDerek Chickles <derek.chickles@caviumnetworks.com>
Signed-off-by: default avatarSatanand Burla <satananda.burla@caviumnetworks.com>
Signed-off-by: default avatarFelix Manlunas <felix.manlunas@caviumnetworks.com>
Signed-off-by: default avatarRaghu Vatsavayi <raghu.vatsavayi@caviumnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7275ebfc
...@@ -127,7 +127,7 @@ static int lio_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ...@@ -127,7 +127,7 @@ static int lio_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
dev_err(&oct->pci_dev->dev, "Unknown link interface reported\n"); dev_err(&oct->pci_dev->dev, "Unknown link interface reported\n");
} }
if (linfo->link.s.status) { if (linfo->link.s.link_up) {
ethtool_cmd_speed_set(ecmd, linfo->link.s.speed); ethtool_cmd_speed_set(ecmd, linfo->link.s.speed);
ecmd->duplex = linfo->link.s.duplex; ecmd->duplex = linfo->link.s.duplex;
} else { } else {
...@@ -222,23 +222,20 @@ static int octnet_gpio_access(struct net_device *netdev, int addr, int val) ...@@ -222,23 +222,20 @@ static int octnet_gpio_access(struct net_device *netdev, int addr, int val)
struct lio *lio = GET_LIO(netdev); struct lio *lio = GET_LIO(netdev);
struct octeon_device *oct = lio->oct_dev; struct octeon_device *oct = lio->oct_dev;
struct octnic_ctrl_pkt nctrl; struct octnic_ctrl_pkt nctrl;
struct octnic_ctrl_params nparams;
int ret = 0; int ret = 0;
memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt)); memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
nctrl.ncmd.u64 = 0; nctrl.ncmd.u64 = 0;
nctrl.ncmd.s.cmd = OCTNET_CMD_GPIO_ACCESS; nctrl.ncmd.s.cmd = OCTNET_CMD_GPIO_ACCESS;
nctrl.ncmd.s.param1 = lio->linfo.ifidx; nctrl.ncmd.s.param1 = addr;
nctrl.ncmd.s.param2 = addr; nctrl.ncmd.s.param2 = val;
nctrl.ncmd.s.param3 = val; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100; nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
nparams.resp_order = OCTEON_RESP_ORDERED; ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams);
if (ret < 0) { if (ret < 0) {
dev_err(&oct->pci_dev->dev, "Failed to configure gpio value\n"); dev_err(&oct->pci_dev->dev, "Failed to configure gpio value\n");
return -EINVAL; return -EINVAL;
...@@ -303,9 +300,10 @@ octnet_mdio45_access(struct lio *lio, int op, int loc, int *value) ...@@ -303,9 +300,10 @@ octnet_mdio45_access(struct lio *lio, int op, int loc, int *value)
mdio_cmd->mdio_addr = loc; mdio_cmd->mdio_addr = loc;
if (op) if (op)
mdio_cmd->value1 = *value; mdio_cmd->value1 = *value;
mdio_cmd->value2 = lio->linfo.ifidx;
octeon_swap_8B_data((u64 *)mdio_cmd, sizeof(struct oct_mdio_cmd) / 8); octeon_swap_8B_data((u64 *)mdio_cmd, sizeof(struct oct_mdio_cmd) / 8);
sc->iq_no = lio->linfo.txpciq[0].s.q_no;
octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC, OPCODE_NIC_MDIO45, octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC, OPCODE_NIC_MDIO45,
0, 0, 0); 0, 0, 0);
...@@ -503,10 +501,10 @@ static void lio_set_msglevel(struct net_device *netdev, u32 msglvl) ...@@ -503,10 +501,10 @@ static void lio_set_msglevel(struct net_device *netdev, u32 msglvl)
if ((msglvl ^ lio->msg_enable) & NETIF_MSG_HW) { if ((msglvl ^ lio->msg_enable) & NETIF_MSG_HW) {
if (msglvl & NETIF_MSG_HW) if (msglvl & NETIF_MSG_HW)
liquidio_set_feature(netdev, liquidio_set_feature(netdev,
OCTNET_CMD_VERBOSE_ENABLE); OCTNET_CMD_VERBOSE_ENABLE, 0);
else else
liquidio_set_feature(netdev, liquidio_set_feature(netdev,
OCTNET_CMD_VERBOSE_DISABLE); OCTNET_CMD_VERBOSE_DISABLE, 0);
} }
lio->msg_enable = msglvl; lio->msg_enable = msglvl;
...@@ -950,7 +948,6 @@ static int lio_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ...@@ -950,7 +948,6 @@ static int lio_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
struct octeon_device *oct = lio->oct_dev; struct octeon_device *oct = lio->oct_dev;
struct oct_link_info *linfo; struct oct_link_info *linfo;
struct octnic_ctrl_pkt nctrl; struct octnic_ctrl_pkt nctrl;
struct octnic_ctrl_params nparams;
int ret = 0; int ret = 0;
/* get the link info */ /* get the link info */
...@@ -978,9 +975,9 @@ static int lio_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ...@@ -978,9 +975,9 @@ static int lio_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
nctrl.ncmd.u64 = 0; nctrl.ncmd.u64 = 0;
nctrl.ncmd.s.cmd = OCTNET_CMD_SET_SETTINGS; nctrl.ncmd.s.cmd = OCTNET_CMD_SET_SETTINGS;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 1000; nctrl.wait_time = 1000;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.ncmd.s.param1 = lio->linfo.ifidx;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
/* Passing the parameters sent by ethtool like Speed, Autoneg & Duplex /* Passing the parameters sent by ethtool like Speed, Autoneg & Duplex
...@@ -990,19 +987,17 @@ static int lio_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ...@@ -990,19 +987,17 @@ static int lio_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
/* Autoneg ON */ /* Autoneg ON */
nctrl.ncmd.s.more = OCTNIC_NCMD_PHY_ON | nctrl.ncmd.s.more = OCTNIC_NCMD_PHY_ON |
OCTNIC_NCMD_AUTONEG_ON; OCTNIC_NCMD_AUTONEG_ON;
nctrl.ncmd.s.param2 = ecmd->advertising; nctrl.ncmd.s.param1 = ecmd->advertising;
} else { } else {
/* Autoneg OFF */ /* Autoneg OFF */
nctrl.ncmd.s.more = OCTNIC_NCMD_PHY_ON; nctrl.ncmd.s.more = OCTNIC_NCMD_PHY_ON;
nctrl.ncmd.s.param3 = ecmd->duplex; nctrl.ncmd.s.param2 = ecmd->duplex;
nctrl.ncmd.s.param2 = ecmd->speed; nctrl.ncmd.s.param1 = ecmd->speed;
} }
nparams.resp_order = OCTEON_RESP_ORDERED; ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams);
if (ret < 0) { if (ret < 0) {
dev_err(&oct->pci_dev->dev, "Failed to set settings\n"); dev_err(&oct->pci_dev->dev, "Failed to set settings\n");
return -1; return -1;
......
...@@ -710,7 +710,7 @@ static void start_txq(struct net_device *netdev) ...@@ -710,7 +710,7 @@ static void start_txq(struct net_device *netdev)
{ {
struct lio *lio = GET_LIO(netdev); struct lio *lio = GET_LIO(netdev);
if (lio->linfo.link.s.status) { if (lio->linfo.link.s.link_up) {
txqs_start(netdev); txqs_start(netdev);
return; return;
} }
...@@ -918,7 +918,7 @@ static void print_link_info(struct net_device *netdev) ...@@ -918,7 +918,7 @@ static void print_link_info(struct net_device *netdev)
if (atomic_read(&lio->ifstate) & LIO_IFSTATE_REGISTERED) { if (atomic_read(&lio->ifstate) & LIO_IFSTATE_REGISTERED) {
struct oct_link_info *linfo = &lio->linfo; 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", netif_info(lio, link, lio->netdev, "%d Mbps %s Duplex UP\n",
linfo->link.s.speed, linfo->link.s.speed,
(linfo->link.s.duplex) ? "Full" : "Half"); (linfo->link.s.duplex) ? "Full" : "Half");
...@@ -940,13 +940,15 @@ static inline void update_link_status(struct net_device *netdev, ...@@ -940,13 +940,15 @@ static inline void update_link_status(struct net_device *netdev,
union oct_link_status *ls) union oct_link_status *ls)
{ {
struct lio *lio = GET_LIO(netdev); 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); print_link_info(netdev);
lio->link_changes++;
if (lio->linfo.link.s.status) { if (lio->linfo.link.s.link_up) {
netif_carrier_on(netdev); netif_carrier_on(netdev);
/* start_txq(netdev); */ /* start_txq(netdev); */
txqs_wake(netdev); txqs_wake(netdev);
...@@ -1219,18 +1221,15 @@ static void octeon_destroy_resources(struct octeon_device *oct) ...@@ -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) static void send_rx_ctrl_cmd(struct lio *lio, int start_stop)
{ {
struct octnic_ctrl_pkt nctrl; struct octnic_ctrl_pkt nctrl;
struct octnic_ctrl_params nparams;
memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt)); memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
nctrl.ncmd.s.cmd = OCTNET_CMD_RX_CTL; nctrl.ncmd.s.cmd = OCTNET_CMD_RX_CTL;
nctrl.ncmd.s.param1 = lio->linfo.ifidx; nctrl.ncmd.s.param1 = start_stop;
nctrl.ncmd.s.param2 = start_stop; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.netpndev = (u64)lio->netdev; nctrl.netpndev = (u64)lio->netdev;
nparams.resp_order = OCTEON_RESP_NORESPONSE; if (octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl) < 0)
if (octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams) < 0)
netif_info(lio, rx_err, lio->netdev, "Failed to send RX Control message\n"); 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) ...@@ -1269,6 +1268,8 @@ static void liquidio_destroy_nic_device(struct octeon_device *oct, int ifidx)
free_netdev(netdev); free_netdev(netdev);
oct->props[ifidx].gmxport = -1;
oct->props[ifidx].netdev = NULL; oct->props[ifidx].netdev = NULL;
} }
...@@ -1833,21 +1834,21 @@ static u16 select_q(struct net_device *dev, struct sk_buff *skb, ...@@ -1833,21 +1834,21 @@ static u16 select_q(struct net_device *dev, struct sk_buff *skb,
* @param len - size of total data received. * @param len - size of total data received.
* @param rh - Control header associated with the packet * @param rh - Control header associated with the packet
* @param param - additional control data with the packet * @param param - additional control data with the packet
* @param arg - farg registered in droq_ops
*/ */
static void static void
liquidio_push_packet(u32 octeon_id, liquidio_push_packet(u32 octeon_id,
void *skbuff, void *skbuff,
u32 len, u32 len,
union octeon_rh *rh, union octeon_rh *rh,
void *param) void *param,
void *arg)
{ {
struct napi_struct *napi = param; struct napi_struct *napi = param;
struct octeon_device *oct = lio_get_device(octeon_id);
struct sk_buff *skb = (struct sk_buff *)skbuff; struct sk_buff *skb = (struct sk_buff *)skbuff;
struct skb_shared_hwtstamps *shhwtstamps; struct skb_shared_hwtstamps *shhwtstamps;
u64 ns; u64 ns;
struct net_device *netdev = struct net_device *netdev = (struct net_device *)arg;
(struct net_device *)oct->props[rh->r_dh.link].netdev;
struct octeon_droq *droq = container_of(param, struct octeon_droq, struct octeon_droq *droq = container_of(param, struct octeon_droq,
napi); napi);
if (netdev) { if (netdev) {
...@@ -2043,10 +2044,10 @@ static int liquidio_napi_poll(struct napi_struct *napi, int budget) ...@@ -2043,10 +2044,10 @@ static int liquidio_napi_poll(struct napi_struct *napi, int budget)
* are for ingress packets. * are for ingress packets.
*/ */
static inline int setup_io_queues(struct octeon_device *octeon_dev, static inline int setup_io_queues(struct octeon_device *octeon_dev,
struct net_device *net_device) int ifidx)
{ {
static int first_time = 1; struct octeon_droq_ops droq_ops;
static struct octeon_droq_ops droq_ops; struct net_device *netdev;
static int cpu_id; static int cpu_id;
static int cpu_id_modulus; static int cpu_id_modulus;
struct octeon_droq *droq; struct octeon_droq *droq;
...@@ -2055,18 +2056,19 @@ static inline int setup_io_queues(struct octeon_device *octeon_dev, ...@@ -2055,18 +2056,19 @@ static inline int setup_io_queues(struct octeon_device *octeon_dev,
struct lio *lio; struct lio *lio;
int num_tx_descs; int num_tx_descs;
lio = GET_LIO(net_device); netdev = octeon_dev->props[ifidx].netdev;
if (first_time) {
first_time = 0; lio = GET_LIO(netdev);
memset(&droq_ops, 0, sizeof(struct octeon_droq_ops));
droq_ops.fptr = liquidio_push_packet; memset(&droq_ops, 0, sizeof(struct octeon_droq_ops));
droq_ops.poll_mode = 1; droq_ops.fptr = liquidio_push_packet;
droq_ops.napi_fn = liquidio_napi_drv_callback; droq_ops.farg = (void *)netdev;
cpu_id = 0;
cpu_id_modulus = num_present_cpus(); 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. */ /* set up DROQs. */
for (q = 0; q < lio->linfo.num_rxpciq; q++) { for (q = 0; q < lio->linfo.num_rxpciq; q++) {
...@@ -2090,7 +2092,11 @@ static inline int setup_io_queues(struct octeon_device *octeon_dev, ...@@ -2090,7 +2092,11 @@ static inline int setup_io_queues(struct octeon_device *octeon_dev,
droq = octeon_dev->droq[q_no]; droq = octeon_dev->droq[q_no];
napi = &droq->napi; 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 */ /* designate a CPU for this droq */
droq->cpu_id = cpu_id; droq->cpu_id = cpu_id;
...@@ -2106,9 +2112,9 @@ static inline int setup_io_queues(struct octeon_device *octeon_dev, ...@@ -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 num_tx_descs = CFG_GET_NUM_TX_DESCS_NIC_IF(octeon_get_conf
(octeon_dev), (octeon_dev),
lio->ifidx); lio->ifidx);
retval = octeon_setup_iq(octeon_dev, lio->linfo.txpciq[q], retval = octeon_setup_iq(octeon_dev, ifidx, q,
num_tx_descs, lio->linfo.txpciq[q], num_tx_descs,
netdev_get_tx_queue(net_device, q)); netdev_get_tx_queue(netdev, q));
if (retval) { if (retval) {
dev_err(&octeon_dev->pci_dev->dev, dev_err(&octeon_dev->pci_dev->dev,
" %s : Runtime IQ(TxQ) creation failed.\n", " %s : Runtime IQ(TxQ) creation failed.\n",
...@@ -2206,7 +2212,8 @@ static int liquidio_stop(struct net_device *netdev) ...@@ -2206,7 +2212,8 @@ static int liquidio_stop(struct net_device *netdev)
netif_info(lio, ifdown, lio->netdev, "Stopping interface!\n"); netif_info(lio, ifdown, lio->netdev, "Stopping interface!\n");
/* Inform that netif carrier is down */ /* Inform that netif carrier is down */
lio->intf_open = 0; lio->intf_open = 0;
lio->linfo.link.s.status = 0; lio->linfo.link.s.link_up = 0;
lio->link_changes++;
netif_carrier_off(netdev); netif_carrier_off(netdev);
...@@ -2345,7 +2352,6 @@ static void liquidio_set_mcast_list(struct net_device *netdev) ...@@ -2345,7 +2352,6 @@ static void liquidio_set_mcast_list(struct net_device *netdev)
struct lio *lio = GET_LIO(netdev); struct lio *lio = GET_LIO(netdev);
struct octeon_device *oct = lio->oct_dev; struct octeon_device *oct = lio->oct_dev;
struct octnic_ctrl_pkt nctrl; struct octnic_ctrl_pkt nctrl;
struct octnic_ctrl_params nparams;
struct netdev_hw_addr *ha; struct netdev_hw_addr *ha;
u64 *mc; u64 *mc;
int ret, i; int ret, i;
...@@ -2356,10 +2362,10 @@ static void liquidio_set_mcast_list(struct net_device *netdev) ...@@ -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. */ /* Create a ctrl pkt command to be sent to core app. */
nctrl.ncmd.u64 = 0; nctrl.ncmd.u64 = 0;
nctrl.ncmd.s.cmd = OCTNET_CMD_SET_MULTI_LIST; nctrl.ncmd.s.cmd = OCTNET_CMD_SET_MULTI_LIST;
nctrl.ncmd.s.param1 = lio->linfo.ifidx; nctrl.ncmd.s.param1 = get_new_flags(netdev);
nctrl.ncmd.s.param2 = get_new_flags(netdev); nctrl.ncmd.s.param2 = mc_count;
nctrl.ncmd.s.param3 = mc_count;
nctrl.ncmd.s.more = mc_count; nctrl.ncmd.s.more = mc_count;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
...@@ -2380,9 +2386,7 @@ static void liquidio_set_mcast_list(struct net_device *netdev) ...@@ -2380,9 +2386,7 @@ static void liquidio_set_mcast_list(struct net_device *netdev)
*/ */
nctrl.wait_time = 0; nctrl.wait_time = 0;
nparams.resp_order = OCTEON_RESP_NORESPONSE; ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams);
if (ret < 0) { if (ret < 0) {
dev_err(&oct->pci_dev->dev, "DEVFLAGS change failed in core (ret: 0x%x)\n", dev_err(&oct->pci_dev->dev, "DEVFLAGS change failed in core (ret: 0x%x)\n",
ret); ret);
...@@ -2400,19 +2404,17 @@ static int liquidio_set_mac(struct net_device *netdev, void *p) ...@@ -2400,19 +2404,17 @@ static int liquidio_set_mac(struct net_device *netdev, void *p)
struct octeon_device *oct = lio->oct_dev; struct octeon_device *oct = lio->oct_dev;
struct sockaddr *addr = (struct sockaddr *)p; struct sockaddr *addr = (struct sockaddr *)p;
struct octnic_ctrl_pkt nctrl; struct octnic_ctrl_pkt nctrl;
struct octnic_ctrl_params nparams;
if ((!is_valid_ether_addr(addr->sa_data)) || if (!is_valid_ether_addr(addr->sa_data))
(ifstate_check(lio, LIO_IFSTATE_RUNNING)))
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt)); memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
nctrl.ncmd.u64 = 0; nctrl.ncmd.u64 = 0;
nctrl.ncmd.s.cmd = OCTNET_CMD_CHANGE_MACADDR; nctrl.ncmd.s.cmd = OCTNET_CMD_CHANGE_MACADDR;
nctrl.ncmd.s.param1 = lio->linfo.ifidx; nctrl.ncmd.s.param1 = 0;
nctrl.ncmd.s.param2 = 0;
nctrl.ncmd.s.more = 1; nctrl.ncmd.s.more = 1;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
nctrl.wait_time = 100; nctrl.wait_time = 100;
...@@ -2421,9 +2423,7 @@ static int liquidio_set_mac(struct net_device *netdev, void *p) ...@@ -2421,9 +2423,7 @@ static int liquidio_set_mac(struct net_device *netdev, void *p)
/* The MAC Address is presented in network byte order. */ /* The MAC Address is presented in network byte order. */
memcpy((u8 *)&nctrl.udd[0] + 2, addr->sa_data, ETH_ALEN); 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);
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams);
if (ret < 0) { if (ret < 0) {
dev_err(&oct->pci_dev->dev, "MAC Address change failed\n"); dev_err(&oct->pci_dev->dev, "MAC Address change failed\n");
return -ENOMEM; return -ENOMEM;
...@@ -2493,7 +2493,6 @@ static int liquidio_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -2493,7 +2493,6 @@ static int liquidio_change_mtu(struct net_device *netdev, int new_mtu)
struct lio *lio = GET_LIO(netdev); struct lio *lio = GET_LIO(netdev);
struct octeon_device *oct = lio->oct_dev; struct octeon_device *oct = lio->oct_dev;
struct octnic_ctrl_pkt nctrl; struct octnic_ctrl_pkt nctrl;
struct octnic_ctrl_params nparams;
int max_frm_size = new_mtu + OCTNET_FRM_HEADER_SIZE; int max_frm_size = new_mtu + OCTNET_FRM_HEADER_SIZE;
int ret = 0; int ret = 0;
...@@ -2513,15 +2512,13 @@ static int liquidio_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -2513,15 +2512,13 @@ static int liquidio_change_mtu(struct net_device *netdev, int new_mtu)
nctrl.ncmd.u64 = 0; nctrl.ncmd.u64 = 0;
nctrl.ncmd.s.cmd = OCTNET_CMD_CHANGE_MTU; nctrl.ncmd.s.cmd = OCTNET_CMD_CHANGE_MTU;
nctrl.ncmd.s.param1 = lio->linfo.ifidx; nctrl.ncmd.s.param1 = new_mtu;
nctrl.ncmd.s.param2 = new_mtu; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100; nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
nparams.resp_order = OCTEON_RESP_ORDERED; ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams);
if (ret < 0) { if (ret < 0) {
dev_err(&oct->pci_dev->dev, "Failed to set MTU\n"); dev_err(&oct->pci_dev->dev, "Failed to set MTU\n");
return -1; return -1;
...@@ -2742,11 +2739,11 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -2742,11 +2739,11 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
* transmitted. * transmitted.
*/ */
if (!(atomic_read(&lio->ifstate) & LIO_IFSTATE_RUNNING) || if (!(atomic_read(&lio->ifstate) & LIO_IFSTATE_RUNNING) ||
(!lio->linfo.link.s.status) || (!lio->linfo.link.s.link_up) ||
(skb->len <= 0)) { (skb->len <= 0)) {
netif_info(lio, tx_err, lio->netdev, netif_info(lio, tx_err, lio->netdev,
"Transmit failed link_status : %d\n", "Transmit failed link_status : %d\n",
lio->linfo.link.s.status); lio->linfo.link.s.link_up);
goto lio_xmit_failed; goto lio_xmit_failed;
} }
...@@ -2789,7 +2786,6 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -2789,7 +2786,6 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
ndata.datasize = skb->len; ndata.datasize = skb->len;
cmdsetup.u64 = 0; cmdsetup.u64 = 0;
cmdsetup.s.ifidx = lio->linfo.ifidx;
cmdsetup.s.iq_no = iq_no; cmdsetup.s.iq_no = iq_no;
if (skb->ip_summed == CHECKSUM_PARTIAL) if (skb->ip_summed == CHECKSUM_PARTIAL)
...@@ -2802,7 +2798,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -2802,7 +2798,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
if (skb_shinfo(skb)->nr_frags == 0) { if (skb_shinfo(skb)->nr_frags == 0) {
cmdsetup.s.u.datasize = skb->len; 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 */ /* Offload checksum calculation for TCP/UDP packets */
ndata.cmd.dptr = dma_map_single(&oct->pci_dev->dev, ndata.cmd.dptr = dma_map_single(&oct->pci_dev->dev,
skb->data, skb->data,
...@@ -2836,7 +2832,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -2836,7 +2832,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
cmdsetup.s.gather = 1; cmdsetup.s.gather = 1;
cmdsetup.s.u.gatherptrs = (skb_shinfo(skb)->nr_frags + 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); memset(g->sg, 0, g->sg_size);
...@@ -2952,27 +2948,24 @@ static void liquidio_tx_timeout(struct net_device *netdev) ...@@ -2952,27 +2948,24 @@ static void liquidio_tx_timeout(struct net_device *netdev)
txqs_wake(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 lio *lio = GET_LIO(netdev);
struct octeon_device *oct = lio->oct_dev; struct octeon_device *oct = lio->oct_dev;
struct octnic_ctrl_pkt nctrl; struct octnic_ctrl_pkt nctrl;
struct octnic_ctrl_params nparams;
int ret = 0; int ret = 0;
memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt)); memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
nctrl.ncmd.u64 = 0; nctrl.ncmd.u64 = 0;
nctrl.ncmd.s.cmd = cmd; nctrl.ncmd.s.cmd = cmd;
nctrl.ncmd.s.param1 = lio->linfo.ifidx; nctrl.ncmd.s.param1 = param1;
nctrl.ncmd.s.param2 = OCTNIC_LROIPV4 | OCTNIC_LROIPV6; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100; nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
nparams.resp_order = OCTEON_RESP_NORESPONSE; ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams);
if (ret < 0) { if (ret < 0) {
dev_err(&oct->pci_dev->dev, "Feature change failed in core (ret: 0x%x)\n", dev_err(&oct->pci_dev->dev, "Feature change failed in core (ret: 0x%x)\n",
ret); ret);
...@@ -3028,10 +3021,12 @@ static int liquidio_set_features(struct net_device *netdev, ...@@ -3028,10 +3021,12 @@ static int liquidio_set_features(struct net_device *netdev,
return 0; return 0;
if ((features & NETIF_F_LRO) && (lio->dev_capability & NETIF_F_LRO)) 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) && else if (!(features & NETIF_F_LRO) &&
(lio->dev_capability & 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; return 0;
} }
...@@ -3102,24 +3097,27 @@ static int lio_nic_info(struct octeon_recv_info *recv_info, void *buf) ...@@ -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_device *oct = (struct octeon_device *)buf;
struct octeon_recv_pkt *recv_pkt = recv_info->recv_pkt; struct octeon_recv_pkt *recv_pkt = recv_info->recv_pkt;
int ifidx = 0; int gmxport = 0;
union oct_link_status *ls; union oct_link_status *ls;
int i; int i;
if ((recv_pkt->buffer_size[0] != sizeof(*ls)) || if (recv_pkt->buffer_size[0] != sizeof(*ls)) {
(recv_pkt->rh.r_nic_info.ifidx > oct->ifcount)) {
dev_err(&oct->pci_dev->dev, "Malformed NIC_INFO, len=%d, ifidx=%d\n", dev_err(&oct->pci_dev->dev, "Malformed NIC_INFO, len=%d, ifidx=%d\n",
recv_pkt->buffer_size[0], recv_pkt->buffer_size[0],
recv_pkt->rh.r_nic_info.ifidx); recv_pkt->rh.r_nic_info.gmxport);
goto nic_info_err; 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]); ls = (union oct_link_status *)get_rbd(recv_pkt->buffer_ptr[0]);
octeon_swap_8B_data((u64 *)ls, (sizeof(union oct_link_status)) >> 3); octeon_swap_8B_data((u64 *)ls, (sizeof(union oct_link_status)) >> 3);
for (i = 0; i < oct->ifcount; i++) {
update_link_status(oct->props[ifidx].netdev, ls); if (oct->props[i].gmxport == gmxport) {
update_link_status(oct->props[i].netdev, ls);
break;
}
}
nic_info_err: nic_info_err:
for (i = 0; i < recv_pkt->buffer_count; i++) for (i = 0; i < recv_pkt->buffer_count; i++)
...@@ -3146,12 +3144,12 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) ...@@ -3146,12 +3144,12 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
struct liquidio_if_cfg_resp *resp; struct liquidio_if_cfg_resp *resp;
struct octdev_props *props; struct octdev_props *props;
int retval, num_iqueues, num_oqueues; int retval, num_iqueues, num_oqueues;
u64 q_mask;
int num_cpus = num_online_cpus(); int num_cpus = num_online_cpus();
union oct_nic_if_cfg if_cfg; union oct_nic_if_cfg if_cfg;
unsigned int base_queue; unsigned int base_queue;
unsigned int gmx_port_id; unsigned int gmx_port_id;
u32 resp_size, ctx_size; u32 resp_size, ctx_size;
u32 ifidx_or_pfnum;
/* This is to handle link status changes */ /* This is to handle link status changes */
octeon_register_dispatch_fn(octeon_dev, OPCODE_NIC, octeon_register_dispatch_fn(octeon_dev, OPCODE_NIC,
...@@ -3187,13 +3185,14 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) ...@@ -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); CFG_GET_BASE_QUE_NIC_IF(octeon_get_conf(octeon_dev), i);
gmx_port_id = gmx_port_id =
CFG_GET_GMXID_NIC_IF(octeon_get_conf(octeon_dev), i); CFG_GET_GMXID_NIC_IF(octeon_get_conf(octeon_dev), i);
ifidx_or_pfnum = i;
if (num_iqueues > num_cpus) if (num_iqueues > num_cpus)
num_iqueues = num_cpus; num_iqueues = num_cpus;
if (num_oqueues > num_cpus) if (num_oqueues > num_cpus)
num_oqueues = num_cpus; num_oqueues = num_cpus;
dev_dbg(&octeon_dev->pci_dev->dev, dev_dbg(&octeon_dev->pci_dev->dev,
"requesting config for interface %d, iqs %d, oqs %d\n", "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; ACCESS_ONCE(ctx->cond) = 0;
ctx->octeon_id = lio_get_device_id(octeon_dev); ctx->octeon_id = lio_get_device_id(octeon_dev);
init_waitqueue_head(&ctx->wc); init_waitqueue_head(&ctx->wc);
...@@ -3203,8 +3202,11 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) ...@@ -3203,8 +3202,11 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
if_cfg.s.num_oqueues = num_oqueues; if_cfg.s.num_oqueues = num_oqueues;
if_cfg.s.base_queue = base_queue; if_cfg.s.base_queue = base_queue;
if_cfg.s.gmx_port_id = gmx_port_id; if_cfg.s.gmx_port_id = gmx_port_id;
sc->iq_no = 0;
octeon_prepare_soft_command(octeon_dev, sc, OPCODE_NIC, octeon_prepare_soft_command(octeon_dev, sc, OPCODE_NIC,
OPCODE_NIC_IF_CFG, i, OPCODE_NIC_IF_CFG, 0,
if_cfg.u64, 0); if_cfg.u64, 0);
sc->callback = if_cfg_callback; sc->callback = if_cfg_callback;
...@@ -3254,8 +3256,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) ...@@ -3254,8 +3256,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
goto setup_nic_dev_fail; goto setup_nic_dev_fail;
} }
props = &octeon_dev->props[i]; SET_NETDEV_DEV(netdev, &octeon_dev->pci_dev->dev);
props->netdev = netdev;
if (num_iqueues > 1) if (num_iqueues > 1)
lionetdevops.ndo_select_queue = select_q; lionetdevops.ndo_select_queue = select_q;
...@@ -3269,18 +3270,18 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) ...@@ -3269,18 +3270,18 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
memset(lio, 0, sizeof(struct lio)); memset(lio, 0, sizeof(struct lio));
lio->linfo.ifidx = resp->cfg_info.ifidx; lio->ifidx = ifidx_or_pfnum;
lio->ifidx = resp->cfg_info.ifidx;
props = &octeon_dev->props[i];
props->gmxport = resp->cfg_info.linfo.gmxport;
props->netdev = netdev;
lio->linfo.num_rxpciq = num_oqueues; lio->linfo.num_rxpciq = num_oqueues;
lio->linfo.num_txpciq = num_iqueues; 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++) { for (j = 0; j < num_oqueues; j++) {
lio->linfo.rxpciq[j].u64 = lio->linfo.rxpciq[j].u64 =
resp->cfg_info.linfo.rxpciq[j].u64; resp->cfg_info.linfo.rxpciq[j].u64;
} }
q_mask = resp->cfg_info.iqmask;
for (j = 0; j < num_iqueues; j++) { for (j = 0; j < num_iqueues; j++) {
lio->linfo.txpciq[j].u64 = lio->linfo.txpciq[j].u64 =
resp->cfg_info.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) ...@@ -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->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
lio->dev_capability = NETIF_F_HIGHDMA lio->dev_capability = NETIF_F_HIGHDMA
| NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
| NETIF_F_SG | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_RXCSUM
| NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GRO
| NETIF_F_LRO; | NETIF_F_TSO | NETIF_F_TSO6
| NETIF_F_LRO;
netif_set_gso_max_size(netdev, OCTNIC_GSO_MAX_SIZE); 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->vlan_features = lio->dev_capability;
netdev->hw_features = lio->dev_capability; netdev->hw_features = lio->dev_capability;
...@@ -3328,7 +3331,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) ...@@ -3328,7 +3331,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
*/ */
lio->txq = lio->linfo.txpciq[0].s.q_no; lio->txq = lio->linfo.txpciq[0].s.q_no;
lio->rxq = lio->linfo.rxpciq[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"); dev_err(&octeon_dev->pci_dev->dev, "I/O queues creation failed\n");
goto setup_nic_dev_fail; goto setup_nic_dev_fail;
} }
...@@ -3347,10 +3350,13 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) ...@@ -3347,10 +3350,13 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
/* Register ethtool support */ /* Register ethtool support */
liquidio_set_ethtool_ops(netdev); 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)) 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 */ /* Register the network device with the OS */
if (register_netdev(netdev)) { if (register_netdev(netdev)) {
...@@ -3362,13 +3368,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) ...@@ -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", "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]); i, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
netif_carrier_off(netdev); netif_carrier_off(netdev);
lio->link_changes++;
if (lio->linfo.link.s.status) {
netif_carrier_on(netdev);
start_txq(netdev);
} else {
netif_carrier_off(netdev);
}
ifstate_set(lio, LIO_IFSTATE_REGISTERED); ifstate_set(lio, LIO_IFSTATE_REGISTERED);
...@@ -3402,7 +3402,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) ...@@ -3402,7 +3402,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
static int liquidio_init_nic_module(struct octeon_device *oct) static int liquidio_init_nic_module(struct octeon_device *oct)
{ {
struct oct_intrmod_cfg *intrmod_cfg; 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)); int num_nic_ports = CFG_GET_NUM_NIC_PORTS(octeon_get_conf(oct));
dev_dbg(&oct->pci_dev->dev, "Initializing network interfaces\n"); dev_dbg(&oct->pci_dev->dev, "Initializing network interfaces\n");
...@@ -3416,6 +3416,9 @@ static int liquidio_init_nic_module(struct octeon_device *oct) ...@@ -3416,6 +3416,9 @@ static int liquidio_init_nic_module(struct octeon_device *oct)
memset(oct->props, 0, memset(oct->props, 0,
sizeof(struct octdev_props) * num_nic_ports); 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); retval = setup_nic_devices(oct);
if (retval) { if (retval) {
dev_err(&oct->pci_dev->dev, "Setup NIC devices failed\n"); dev_err(&oct->pci_dev->dev, "Setup NIC devices failed\n");
......
...@@ -260,19 +260,19 @@ union octnet_cmd { ...@@ -260,19 +260,19 @@ union octnet_cmd {
u64 more:6; /* How many udd words follow the command */ u64 more:6; /* How many udd words follow the command */
u64 param1:29; u64 reserved:29;
u64 param2:16; u64 param1:16;
u64 param3:8; u64 param2:8;
#else #else
u64 param3:8; u64 param2:8;
u64 param2:16; u64 param1:16;
u64 param1:29; u64 reserved:29;
u64 more:6; u64 more:6;
...@@ -414,10 +414,9 @@ union octeon_rh { ...@@ -414,10 +414,9 @@ union octeon_rh {
u64 opcode:4; u64 opcode:4;
u64 subcode:8; u64 subcode:8;
u64 len:3; /** additional 64-bit words */ u64 len:3; /** additional 64-bit words */
u64 rid:13; u64 reserved:8;
u64 reserved:4;
u64 extra:25; u64 extra:25;
u64 ifidx:7; u64 gmxport:16;
} r_nic_info; } r_nic_info;
#else #else
u64 u64; u64 u64;
...@@ -450,10 +449,9 @@ union octeon_rh { ...@@ -450,10 +449,9 @@ union octeon_rh {
u64 opcode:4; u64 opcode:4;
} r_core_drv_init; } r_core_drv_init;
struct { struct {
u64 ifidx:7; u64 gmxport:16;
u64 extra:25; u64 extra:25;
u64 reserved:4; u64 reserved:8;
u64 rid:13;
u64 len:3; /** additional 64-bit words */ u64 len:3; /** additional 64-bit words */
u64 subcode:8; u64 subcode:8;
u64 opcode:4; u64 opcode:4;
...@@ -467,7 +465,7 @@ union octnic_packet_params { ...@@ -467,7 +465,7 @@ union octnic_packet_params {
u32 u32; u32 u32;
struct { struct {
#ifdef __BIG_ENDIAN_BITFIELD #ifdef __BIG_ENDIAN_BITFIELD
u32 reserved:16; u32 reserved:24;
u32 ip_csum:1; /* Perform IP header checksum(s) */ u32 ip_csum:1; /* Perform IP header checksum(s) */
/* Perform Outer transport header checksum */ /* Perform Outer transport header checksum */
u32 transport_csum:1; u32 transport_csum:1;
...@@ -475,15 +473,13 @@ union octnic_packet_params { ...@@ -475,15 +473,13 @@ union octnic_packet_params {
u32 tnl_csum:1; u32 tnl_csum:1;
u32 tsflag:1; /* Timestamp this packet */ u32 tsflag:1; /* Timestamp this packet */
u32 ipsec_ops:4; /* IPsec operation */ u32 ipsec_ops:4; /* IPsec operation */
u32 ifidx:8;
#else #else
u32 ifidx:8;
u32 ipsec_ops:4; u32 ipsec_ops:4;
u32 tsflag:1; u32 tsflag:1;
u32 tnl_csum:1; u32 tnl_csum:1;
u32 transport_csum:1; u32 transport_csum:1;
u32 ip_csum:1; u32 ip_csum:1;
u32 reserved:16; u32 reserved:24;
#endif #endif
} s; } s;
}; };
...@@ -495,21 +491,21 @@ union oct_link_status { ...@@ -495,21 +491,21 @@ union oct_link_status {
struct { struct {
#ifdef __BIG_ENDIAN_BITFIELD #ifdef __BIG_ENDIAN_BITFIELD
u64 duplex:8; u64 duplex:8;
u64 status:8;
u64 mtu:16; u64 mtu:16;
u64 speed:16; u64 speed:16;
u64 link_up:1;
u64 autoneg:1; u64 autoneg:1;
u64 interface:4; u64 interface:4;
u64 pause:1; u64 pause:1;
u64 reserved:10; u64 reserved:17;
#else #else
u64 reserved:10; u64 reserved:17;
u64 pause:1; u64 pause:1;
u64 interface:4; u64 interface:4;
u64 autoneg:1; u64 autoneg:1;
u64 link_up:1;
u64 speed:16; u64 speed:16;
u64 mtu:16; u64 mtu:16;
u64 status:8;
u64 duplex:8; u64 duplex:8;
#endif #endif
} s; } s;
...@@ -561,17 +557,15 @@ struct oct_link_info { ...@@ -561,17 +557,15 @@ struct oct_link_info {
u64 hw_addr; u64 hw_addr;
#ifdef __BIG_ENDIAN_BITFIELD #ifdef __BIG_ENDIAN_BITFIELD
u16 gmxport; u64 gmxport:16;
u8 rsvd[3]; u64 rsvd:32;
u8 num_txpciq; u64 num_txpciq:8;
u8 num_rxpciq; u64 num_rxpciq:8;
u8 ifidx;
#else #else
u8 ifidx; u64 num_rxpciq:8;
u8 num_rxpciq; u64 num_txpciq:8;
u8 num_txpciq; u64 rsvd:32;
u8 rsvd[3]; u64 gmxport:16;
u16 gmxport;
#endif #endif
union oct_txpciq txpciq[MAX_IOQS_PER_NICIF]; union oct_txpciq txpciq[MAX_IOQS_PER_NICIF];
...@@ -581,7 +575,6 @@ struct oct_link_info { ...@@ -581,7 +575,6 @@ struct oct_link_info {
#define OCT_LINK_INFO_SIZE (sizeof(struct oct_link_info)) #define OCT_LINK_INFO_SIZE (sizeof(struct oct_link_info))
struct liquidio_if_cfg_info { struct liquidio_if_cfg_info {
u64 ifidx;
u64 iqmask; /** mask for IQs enabled for the port */ u64 iqmask; /** mask for IQs enabled for the port */
u64 oqmask; /** mask for OQs enabled for the port */ u64 oqmask; /** mask for OQs enabled for the port */
struct oct_link_info linfo; /** initial link information */ struct oct_link_info linfo; /** initial link information */
......
...@@ -766,7 +766,9 @@ int octeon_setup_instr_queues(struct octeon_device *oct) ...@@ -766,7 +766,9 @@ int octeon_setup_instr_queues(struct octeon_device *oct)
if (!oct->instr_queue[0]) if (!oct->instr_queue[0])
return 1; return 1;
memset(oct->instr_queue[0], 0, sizeof(struct octeon_instr_queue)); memset(oct->instr_queue[0], 0, sizeof(struct octeon_instr_queue));
oct->instr_queue[0]->q_index = 0;
oct->instr_queue[0]->app_ctx = (void *)(size_t)0; oct->instr_queue[0]->app_ctx = (void *)(size_t)0;
oct->instr_queue[0]->ifidx = 0;
txpciq.u64 = 0; txpciq.u64 = 0;
txpciq.s.q_no = iq_no; txpciq.s.q_no = iq_no;
txpciq.s.use_qpg = 0; txpciq.s.use_qpg = 0;
......
...@@ -267,6 +267,7 @@ struct octdev_props { ...@@ -267,6 +267,7 @@ struct octdev_props {
/* Each interface in the Octeon device has a network /* Each interface in the Octeon device has a network
* device pointer (used for OS specific calls). * device pointer (used for OS specific calls).
*/ */
int gmxport;
struct net_device *netdev; struct net_device *netdev;
}; };
......
...@@ -696,7 +696,8 @@ octeon_droq_fast_process_packets(struct octeon_device *oct, ...@@ -696,7 +696,8 @@ octeon_droq_fast_process_packets(struct octeon_device *oct,
if (droq->ops.fptr) { if (droq->ops.fptr) {
droq->ops.fptr(oct->octeon_id, droq->ops.fptr(oct->octeon_id,
nicbuf, pkt_len, nicbuf, pkt_len,
rh, &droq->napi); rh, &droq->napi,
droq->ops.farg);
} else { } else {
recv_buffer_free(nicbuf); recv_buffer_free(nicbuf);
} }
...@@ -963,6 +964,7 @@ int octeon_unregister_droq_ops(struct octeon_device *oct, u32 q_no) ...@@ -963,6 +964,7 @@ int octeon_unregister_droq_ops(struct octeon_device *oct, u32 q_no)
spin_lock_irqsave(&droq->lock, flags); spin_lock_irqsave(&droq->lock, flags);
droq->ops.fptr = NULL; droq->ops.fptr = NULL;
droq->ops.farg = NULL;
droq->ops.drop_on_max = 0; droq->ops.drop_on_max = 0;
spin_unlock_irqrestore(&droq->lock, flags); spin_unlock_irqrestore(&droq->lock, flags);
......
...@@ -231,7 +231,8 @@ struct octeon_droq_ops { ...@@ -231,7 +231,8 @@ struct octeon_droq_ops {
* data in the buffer. The receive header gives the port * data in the buffer. The receive header gives the port
* number to the caller. Function pointer is set by caller. * number to the caller. Function pointer is set by caller.
*/ */
void (*fptr)(u32, void *, u32, union octeon_rh *, void *); void (*fptr)(u32, void *, u32, union octeon_rh *, void *, void *);
void *farg;
/* This function will be called by the driver for all NAPI related /* This function will be called by the driver for all NAPI related
* events. The first param is the octeon id. The second param is the * events. The first param is the octeon id. The second param is the
......
...@@ -147,6 +147,13 @@ struct octeon_instr_queue { ...@@ -147,6 +147,13 @@ struct octeon_instr_queue {
/** Application context */ /** Application context */
void *app_ctx; void *app_ctx;
/* network stack queue index */
int q_index;
/*os ifidx associated with this queue */
int ifidx;
}; };
/*---------------------- INSTRUCTION FORMAT ----------------------------*/ /*---------------------- INSTRUCTION FORMAT ----------------------------*/
...@@ -314,7 +321,8 @@ void octeon_prepare_soft_command(struct octeon_device *oct, ...@@ -314,7 +321,8 @@ void octeon_prepare_soft_command(struct octeon_device *oct,
int octeon_send_soft_command(struct octeon_device *oct, int octeon_send_soft_command(struct octeon_device *oct,
struct octeon_soft_command *sc); struct octeon_soft_command *sc);
int octeon_setup_iq(struct octeon_device *oct, union oct_txpciq, int octeon_setup_iq(struct octeon_device *oct, int ifidx,
u32 num_descs, void *app_ctx); int q_index, union oct_txpciq iq_no, u32 num_descs,
void *app_ctx);
#endif /* __OCTEON_IQ_H__ */ #endif /* __OCTEON_IQ_H__ */
...@@ -67,6 +67,9 @@ struct lio { ...@@ -67,6 +67,9 @@ struct lio {
/** Link information sent by the core application for this interface. */ /** Link information sent by the core application for this interface. */
struct oct_link_info linfo; struct oct_link_info linfo;
/** counter of link changes */
u64 link_changes;
/** Size of Tx queue for this octeon device. */ /** Size of Tx queue for this octeon device. */
u32 tx_qsize; u32 tx_qsize;
...@@ -111,8 +114,9 @@ struct lio { ...@@ -111,8 +114,9 @@ struct lio {
* \brief Enable or disable feature * \brief Enable or disable feature
* @param netdev pointer to network device * @param netdev pointer to network device
* @param cmd Command that just requires acknowledgment * @param cmd Command that just requires acknowledgment
* @param param1 Parameter to command
*/ */
int liquidio_set_feature(struct net_device *netdev, int cmd); int liquidio_set_feature(struct net_device *netdev, int cmd, u16 param1);
/** /**
* \brief Link control command completion callback * \brief Link control command completion callback
......
...@@ -119,8 +119,7 @@ static void octnet_link_ctrl_callback(struct octeon_device *oct, ...@@ -119,8 +119,7 @@ static void octnet_link_ctrl_callback(struct octeon_device *oct,
static inline struct octeon_soft_command static inline struct octeon_soft_command
*octnic_alloc_ctrl_pkt_sc(struct octeon_device *oct, *octnic_alloc_ctrl_pkt_sc(struct octeon_device *oct,
struct octnic_ctrl_pkt *nctrl, struct octnic_ctrl_pkt *nctrl)
struct octnic_ctrl_params nparams)
{ {
struct octeon_soft_command *sc = NULL; struct octeon_soft_command *sc = NULL;
u8 *data; u8 *data;
...@@ -143,7 +142,7 @@ static inline struct octeon_soft_command ...@@ -143,7 +142,7 @@ static inline struct octeon_soft_command
data = (u8 *)sc->virtdptr; data = (u8 *)sc->virtdptr;
memcpy(data, &nctrl->ncmd, OCTNET_CMD_SIZE); memcpy(data, &nctrl->ncmd, OCTNET_CMD_SIZE);
octeon_swap_8B_data((u64 *)data, (OCTNET_CMD_SIZE >> 3)); octeon_swap_8B_data((u64 *)data, (OCTNET_CMD_SIZE >> 3));
...@@ -152,6 +151,8 @@ static inline struct octeon_soft_command ...@@ -152,6 +151,8 @@ static inline struct octeon_soft_command
memcpy(data + OCTNET_CMD_SIZE, nctrl->udd, uddsize); memcpy(data + OCTNET_CMD_SIZE, nctrl->udd, uddsize);
} }
sc->iq_no = (u32)nctrl->iq_no;
octeon_prepare_soft_command(oct, sc, OPCODE_NIC, OPCODE_NIC_CMD, octeon_prepare_soft_command(oct, sc, OPCODE_NIC, OPCODE_NIC_CMD,
0, 0, 0); 0, 0, 0);
...@@ -164,13 +165,12 @@ static inline struct octeon_soft_command ...@@ -164,13 +165,12 @@ static inline struct octeon_soft_command
int int
octnet_send_nic_ctrl_pkt(struct octeon_device *oct, octnet_send_nic_ctrl_pkt(struct octeon_device *oct,
struct octnic_ctrl_pkt *nctrl, struct octnic_ctrl_pkt *nctrl)
struct octnic_ctrl_params nparams)
{ {
int retval; int retval;
struct octeon_soft_command *sc = NULL; struct octeon_soft_command *sc = NULL;
sc = octnic_alloc_ctrl_pkt_sc(oct, nctrl, nparams); sc = octnic_alloc_ctrl_pkt_sc(oct, nctrl);
if (!sc) { if (!sc) {
dev_err(&oct->pci_dev->dev, "%s soft command alloc failed\n", dev_err(&oct->pci_dev->dev, "%s soft command alloc failed\n",
__func__); __func__);
......
...@@ -52,6 +52,9 @@ struct octnic_ctrl_pkt { ...@@ -52,6 +52,9 @@ struct octnic_ctrl_pkt {
/** Additional data that may be needed by some commands. */ /** Additional data that may be needed by some commands. */
u64 udd[MAX_NCTRL_UDD]; u64 udd[MAX_NCTRL_UDD];
/** Input queue to use to send this command. */
u64 iq_no;
/** Time to wait for Octeon software to respond to this control command. /** Time to wait for Octeon software to respond to this control command.
* If wait_time is 0, OSI assumes no response is expected. * If wait_time is 0, OSI assumes no response is expected.
*/ */
...@@ -100,8 +103,7 @@ union octnic_cmd_setup { ...@@ -100,8 +103,7 @@ union octnic_cmd_setup {
u32 ip_csum:1; u32 ip_csum:1;
u32 transport_csum:1; u32 transport_csum:1;
u32 tnl_csum:1; u32 tnl_csum:1;
u32 ifidx:8; u32 rsvd:19;
u32 rsvd:11;
union { union {
u32 datasize; u32 datasize;
...@@ -113,10 +115,6 @@ union octnic_cmd_setup { ...@@ -113,10 +115,6 @@ union octnic_cmd_setup {
}; };
struct octnic_ctrl_params {
u32 resp_order;
};
static inline int octnet_iq_is_full(struct octeon_device *oct, u32 q_no) static inline int octnet_iq_is_full(struct octeon_device *oct, u32 q_no)
{ {
return ((u32)atomic_read(&oct->instr_queue[q_no]->instr_pending) return ((u32)atomic_read(&oct->instr_queue[q_no]->instr_pending)
...@@ -131,12 +129,13 @@ static inline int octnet_iq_is_full(struct octeon_device *oct, u32 q_no) ...@@ -131,12 +129,13 @@ static inline int octnet_iq_is_full(struct octeon_device *oct, u32 q_no)
* Assumes the cmd instruction is pre-allocated, but no fields are filled in. * Assumes the cmd instruction is pre-allocated, but no fields are filled in.
*/ */
static inline void static inline void
octnet_prepare_pci_cmd(struct octeon_instr_64B *cmd, octnet_prepare_pci_cmd(struct octeon_device *oct, struct octeon_instr_64B *cmd,
union octnic_cmd_setup *setup, u32 tag) union octnic_cmd_setup *setup, u32 tag)
{ {
struct octeon_instr_ih *ih; struct octeon_instr_ih *ih;
struct octeon_instr_irh *irh; struct octeon_instr_irh *irh;
union octnic_packet_params packet_params; union octnic_packet_params packet_params;
int port;
memset(cmd, 0, sizeof(struct octeon_instr_64B)); memset(cmd, 0, sizeof(struct octeon_instr_64B));
...@@ -150,13 +149,15 @@ octnet_prepare_pci_cmd(struct octeon_instr_64B *cmd, ...@@ -150,13 +149,15 @@ octnet_prepare_pci_cmd(struct octeon_instr_64B *cmd,
ih->tagtype = ORDERED_TAG; ih->tagtype = ORDERED_TAG;
ih->grp = DEFAULT_POW_GRP; ih->grp = DEFAULT_POW_GRP;
port = (int)oct->instr_queue[setup->s.iq_no]->txpciq.s.port;
if (tag) if (tag)
ih->tag = tag; ih->tag = tag;
else else
ih->tag = LIO_DATA(setup->s.ifidx); ih->tag = LIO_DATA(port);
ih->raw = 1; ih->raw = 1;
ih->qos = (setup->s.ifidx & 3) + 4; /* map qos based on interface */ ih->qos = (port & 3) + 4; /* map qos based on interface */
if (!setup->s.gather) { if (!setup->s.gather) {
ih->dlengsz = setup->s.u.datasize; ih->dlengsz = setup->s.u.datasize;
...@@ -175,7 +176,6 @@ octnet_prepare_pci_cmd(struct octeon_instr_64B *cmd, ...@@ -175,7 +176,6 @@ octnet_prepare_pci_cmd(struct octeon_instr_64B *cmd,
packet_params.s.ip_csum = setup->s.ip_csum; packet_params.s.ip_csum = setup->s.ip_csum;
packet_params.s.transport_csum = setup->s.transport_csum; packet_params.s.transport_csum = setup->s.transport_csum;
packet_params.s.tnl_csum = setup->s.tnl_csum; packet_params.s.tnl_csum = setup->s.tnl_csum;
packet_params.s.ifidx = setup->s.ifidx;
packet_params.s.tsflag = setup->s.timestamp; packet_params.s.tsflag = setup->s.timestamp;
irh->ossp = packet_params.u32; irh->ossp = packet_params.u32;
...@@ -216,7 +216,6 @@ int octnet_send_nic_data_pkt(struct octeon_device *oct, ...@@ -216,7 +216,6 @@ int octnet_send_nic_data_pkt(struct octeon_device *oct,
*/ */
int int
octnet_send_nic_ctrl_pkt(struct octeon_device *oct, octnet_send_nic_ctrl_pkt(struct octeon_device *oct,
struct octnic_ctrl_pkt *nctrl, struct octnic_ctrl_pkt *nctrl);
struct octnic_ctrl_params nparams);
#endif #endif
...@@ -202,6 +202,8 @@ int octeon_delete_instr_queue(struct octeon_device *oct, u32 iq_no) ...@@ -202,6 +202,8 @@ int octeon_delete_instr_queue(struct octeon_device *oct, u32 iq_no)
/* Return 0 on success, 1 on failure */ /* Return 0 on success, 1 on failure */
int octeon_setup_iq(struct octeon_device *oct, int octeon_setup_iq(struct octeon_device *oct,
int ifidx,
int q_index,
union oct_txpciq txpciq, union oct_txpciq txpciq,
u32 num_descs, u32 num_descs,
void *app_ctx) void *app_ctx)
...@@ -227,7 +229,10 @@ int octeon_setup_iq(struct octeon_device *oct, ...@@ -227,7 +229,10 @@ int octeon_setup_iq(struct octeon_device *oct,
memset(oct->instr_queue[iq_no], 0, memset(oct->instr_queue[iq_no], 0,
sizeof(struct octeon_instr_queue)); sizeof(struct octeon_instr_queue));
oct->instr_queue[iq_no]->q_index = q_index;
oct->instr_queue[iq_no]->app_ctx = app_ctx; oct->instr_queue[iq_no]->app_ctx = app_ctx;
oct->instr_queue[iq_no]->ifidx = ifidx;
if (octeon_init_instr_queue(oct, txpciq, num_descs)) { if (octeon_init_instr_queue(oct, txpciq, num_descs)) {
vfree(oct->instr_queue[iq_no]); vfree(oct->instr_queue[iq_no]);
oct->instr_queue[iq_no] = NULL; oct->instr_queue[iq_no] = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment